Merge remote branch 'cworth/master'

Conflicts:
	ast_to_hir.cpp
	ir.cpp

This brings in the talloc-based memory management work, so that the
compiler (almost) no longer leaks memory.
diff --git a/ast.h b/ast.h
index 782e2c7..de300e7 100644
--- a/ast.h
+++ b/ast.h
@@ -36,6 +36,25 @@
 
 class ast_node {
 public:
+   /* Callers of this talloc-based new need not call delete. It's
+    * easier to just talloc_free 'ctx' (or any of its ancestors). */
+   static void* operator new(size_t size, void *ctx)
+   {
+      void *node;
+
+      node = talloc_size(ctx, size);
+      assert(node != NULL);
+
+      return node;
+   }
+
+   /* If the user *does* call delete, that's OK, we will just
+    * talloc_free in that case. */
+   static void operator delete(void *table)
+   {
+      talloc_free(table);
+   }
+
    virtual void print(void) const;
    virtual ir_rvalue *hir(exec_list *instructions,
 			  struct _mesa_glsl_parse_state *state);
diff --git a/ast_function.cpp b/ast_function.cpp
index ff2dfa5..761af00 100644
--- a/ast_function.cpp
+++ b/ast_function.cpp
@@ -54,6 +54,8 @@
 	     YYLTYPE *loc, exec_list *actual_parameters,
 	     struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
+
    const ir_function_signature *sig =
       f->matching_signature(actual_parameters);
 
@@ -93,7 +95,7 @@
       /* FINISHME: The list of actual parameters needs to be modified to
        * FINISHME: include any necessary conversions.
        */
-      return new ir_call(sig, actual_parameters);
+      return new(ctx) ir_call(sig, actual_parameters);
    } else {
       /* FINISHME: Log a better error message here.  G++ will show the types
        * FINISHME: of the actual parameters and the set of candidate
@@ -102,7 +104,7 @@
        */
       _mesa_glsl_error(loc, state, "no matching function for call to `%s'",
 		       f->name);
-      return ir_call::get_error_instruction();
+      return ir_call::get_error_instruction(ctx);
    }
 }
 
@@ -112,11 +114,12 @@
 		       YYLTYPE *loc, exec_list *actual_parameters,
 		       struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
    ir_function *f = state->symbols->get_function(name);
 
    if (f == NULL) {
       _mesa_glsl_error(loc, state, "function `%s' undeclared", name);
-      return ir_call::get_error_instruction();
+      return ir_call::get_error_instruction(ctx);
    }
 
    /* Once we've determined that the function being called might exist, try
@@ -132,6 +135,7 @@
 static ir_rvalue *
 convert_component(ir_rvalue *src, const glsl_type *desired_type)
 {
+   void *ctx = talloc_parent(src);
    const unsigned a = desired_type->base_type;
    const unsigned b = src->type->base_type;
    ir_expression *result = NULL;
@@ -149,22 +153,22 @@
    case GLSL_TYPE_UINT:
    case GLSL_TYPE_INT:
       if (b == GLSL_TYPE_FLOAT)
-	 result = new ir_expression(ir_unop_f2i, desired_type, src, NULL);
+	 result = new(ctx) ir_expression(ir_unop_f2i, desired_type, src, NULL);
       else {
 	 assert(b == GLSL_TYPE_BOOL);
-	 result = new ir_expression(ir_unop_b2i, desired_type, src, NULL);
+	 result = new(ctx) ir_expression(ir_unop_b2i, desired_type, src, NULL);
       }
       break;
    case GLSL_TYPE_FLOAT:
       switch (b) {
       case GLSL_TYPE_UINT:
-	 result = new ir_expression(ir_unop_u2f, desired_type, src, NULL);
+	 result = new(ctx) ir_expression(ir_unop_u2f, desired_type, src, NULL);
 	 break;
       case GLSL_TYPE_INT:
-	 result = new ir_expression(ir_unop_i2f, desired_type, src, NULL);
+	 result = new(ctx) ir_expression(ir_unop_i2f, desired_type, src, NULL);
 	 break;
       case GLSL_TYPE_BOOL:
-	 result = new ir_expression(ir_unop_b2f, desired_type, src, NULL);
+	 result = new(ctx) ir_expression(ir_unop_b2f, desired_type, src, NULL);
 	 break;
       }
       break;
@@ -172,12 +176,12 @@
       ir_constant *zero = NULL;
 
       switch (b) {
-      case GLSL_TYPE_UINT:  zero = new ir_constant(unsigned(0)); break;
-      case GLSL_TYPE_INT:   zero = new ir_constant(int(0));      break;
-      case GLSL_TYPE_FLOAT: zero = new ir_constant(0.0f);        break;
+      case GLSL_TYPE_UINT:  zero = new(ctx) ir_constant(unsigned(0)); break;
+      case GLSL_TYPE_INT:   zero = new(ctx) ir_constant(int(0));      break;
+      case GLSL_TYPE_FLOAT: zero = new(ctx) ir_constant(0.0f);        break;
       }
 
-      result = new ir_expression(ir_binop_nequal, desired_type, src, zero);
+      result = new(ctx) ir_expression(ir_binop_nequal, desired_type, src, zero);
    }
    }
 
@@ -194,6 +198,7 @@
 static ir_rvalue *
 dereference_component(ir_rvalue *src, unsigned component)
 {
+   void *ctx = talloc_parent(src);
    assert(component < src->type->components());
 
    /* If the source is a constant, just create a new constant instead of a
@@ -201,12 +206,12 @@
     */
    ir_constant *constant = src->as_constant();
    if (constant)
-      return new ir_constant(constant, component);
+      return new(ctx) ir_constant(constant, component);
 
    if (src->type->is_scalar()) {
       return src;
    } else if (src->type->is_vector()) {
-      return new ir_swizzle(src, component, 0, 0, 0, 1);
+      return new(ctx) ir_swizzle(src, component, 0, 0, 0, 1);
    } else {
       assert(src->type->is_matrix());
 
@@ -215,8 +220,8 @@
        */
       const int c = component / src->type->column_type()->vector_elements;
       const int r = component % src->type->column_type()->vector_elements;
-      ir_constant *const col_index = new ir_constant(c);
-      ir_dereference *const col = new ir_dereference_array(src, col_index);
+      ir_constant *const col_index = new(ctx) ir_constant(c);
+      ir_dereference *const col = new(ctx) ir_dereference_array(src, col_index);
 
       col->type = src->type->column_type();
 
@@ -234,6 +239,7 @@
 			  YYLTYPE *loc, exec_list *parameters,
 			  struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
    /* Array constructors come in two forms: sized and unsized.  Sized array
     * constructors look like 'vec4[2](a, b)', where 'a' and 'b' are vec4
     * variables.  In this case the number of parameters must exactly match the
@@ -268,12 +274,13 @@
 		       "parameter%s",
 		       (constructor_type->length != 0) ? "at least" : "exactly",
 		       min_param, (min_param <= 1) ? "" : "s");
-      return ir_call::get_error_instruction();
+      return ir_call::get_error_instruction(ctx);
    }
 
    if (constructor_type->length == 0) {
       constructor_type =
-	 glsl_type::get_array_instance(constructor_type->element_type(),
+	 glsl_type::get_array_instance(state,
+				       constructor_type->element_type(),
 				       parameter_count);
       assert(constructor_type != NULL);
       assert(constructor_type->length == parameter_count);
@@ -306,6 +313,7 @@
 			    YYLTYPE *loc, exec_list *parameters,
 			    struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
    bool all_parameters_are_constant = true;
 
    exec_node *node = parameters->head;
@@ -338,7 +346,7 @@
    if (!all_parameters_are_constant)
       return NULL;
 
-   return new ir_constant(constructor_type, parameters);
+   return new(ctx) ir_constant(constructor_type, parameters);
 }
 
 
@@ -440,6 +448,7 @@
 ast_function_expression::hir(exec_list *instructions,
 			     struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
    /* There are three sorts of function calls.
     *
     * 1. contstructors - The first subexpression is an ast_type_specifier.
@@ -462,14 +471,14 @@
       if (constructor_type->is_sampler()) {
 	 _mesa_glsl_error(& loc, state, "cannot construct sampler type `%s'",
 			  constructor_type->name);
-	 return ir_call::get_error_instruction();
+	 return ir_call::get_error_instruction(ctx);
       }
 
       if (constructor_type->is_array()) {
 	 if (state->language_version <= 110) {
 	    _mesa_glsl_error(& loc, state,
 			     "array constructors forbidden in GLSL 1.10");
-	    return ir_call::get_error_instruction();
+	    return ir_call::get_error_instruction(ctx);
 	 }
 
 	 return process_array_constructor(instructions, constructor_type,
@@ -519,7 +528,7 @@
 	    _mesa_glsl_error(& loc, state, "too few components to construct "
 			     "`%s'",
 			     constructor_type->name);
-	    return ir_call::get_error_instruction();
+	    return ir_call::get_error_instruction(ctx);
 	 }
 
 	 foreach_list (n, &this->expressions) {
@@ -549,14 +558,14 @@
 	       _mesa_glsl_error(& loc, state, "too many parameters to `%s' "
 				"constructor",
 				constructor_type->name);
-	       return ir_call::get_error_instruction();
+	       return ir_call::get_error_instruction(ctx);
 	    }
 
 	    if (!result->type->is_numeric() && !result->type->is_boolean()) {
 	       _mesa_glsl_error(& loc, state, "cannot construct `%s' from a "
 				"non-numeric data type",
 				constructor_type->name);
-	       return ir_call::get_error_instruction();
+	       return ir_call::get_error_instruction(ctx);
 	    }
 
 	    /* Count the number of matrix and nonmatrix parameters.  This
@@ -574,11 +583,13 @@
 	     * glsl-vs-constructor-call.shader_test.
 	     */
 	    if (result->type->components() >= 1 && !result->as_constant()) {
-	       result_var = new ir_variable(result->type, "constructor_tmp");
+	       result_var = new(ctx) ir_variable(result->type,
+						 "constructor_tmp");
 	       ir_dereference_variable *lhs;
 
-	       lhs = new ir_dereference_variable(result_var);
-	       instructions->push_tail(new ir_assignment(lhs, result, NULL));
+	       lhs = new(ctx) ir_dereference_variable(result_var);
+	       instructions->push_tail(new(ctx) ir_assignment(lhs,
+							      result, NULL));
 	    }
 
 	    /* Process each of the components of the parameter.  Dereference
@@ -592,7 +603,7 @@
 	       ir_rvalue *component;
 
 	       if (result_var) {
-		  ir_dereference *d = new ir_dereference_variable(result_var);
+		  ir_dereference *d = new(ctx) ir_dereference_variable(result_var);
 		  component = dereference_component(d, i);
 	       } else {
 		  component = dereference_component(result, i);
@@ -629,7 +640,7 @@
 	    _mesa_glsl_error(& loc, state, "cannot construct `%s' from a "
 			     "matrix in GLSL 1.10",
 			     constructor_type->name);
-	    return ir_call::get_error_instruction();
+	    return ir_call::get_error_instruction(ctx);
 	 }
 
 	 /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec:
@@ -643,7 +654,7 @@
 	    _mesa_glsl_error(& loc, state, "for matrix `%s' constructor, "
 			     "matrix must be only parameter",
 			     constructor_type->name);
-	    return ir_call::get_error_instruction();
+	    return ir_call::get_error_instruction(ctx);
 	 }
 
 	 /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec:
@@ -656,14 +667,14 @@
 	    _mesa_glsl_error(& loc, state, "too few components to construct "
 			     "`%s'",
 			     constructor_type->name);
-	    return ir_call::get_error_instruction();
+	    return ir_call::get_error_instruction(ctx);
 	 }
 
 	 ir_function *f = state->symbols->get_function(constructor_type->name);
 	 if (f == NULL) {
 	    _mesa_glsl_error(& loc, state, "no constructor for type `%s'",
 			     constructor_type->name);
-	    return ir_call::get_error_instruction();
+	    return ir_call::get_error_instruction(ctx);
 	 }
 
 	 const ir_function_signature *sig =
@@ -674,7 +685,8 @@
 	     */
 	    if (all_parameters_are_constant) {
 	       if (components_used >= type_components)
-		  return new ir_constant(sig->return_type, & actual_parameters);
+		  return new(ctx) ir_constant(sig->return_type,
+					      & actual_parameters);
 
 	       assert(sig->return_type->is_vector()
 		      || sig->return_type->is_matrix());
@@ -695,9 +707,9 @@
 		  generate_constructor_vector(sig->return_type, initializer,
 					      &data);
 
-	       return new ir_constant(sig->return_type, &data);
+	       return new(ctx) ir_constant(sig->return_type, &data);
 	    } else
-	       return new ir_call(sig, & actual_parameters);
+	       return new(ctx) ir_call(sig, & actual_parameters);
 	 } else {
 	    /* FINISHME: Log a better error message here.  G++ will show the
 	     * FINSIHME: types of the actual parameters and the set of
@@ -706,11 +718,11 @@
 	     */
 	    _mesa_glsl_error(& loc, state, "no matching constructor for `%s'",
 			     constructor_type->name);
-	    return ir_call::get_error_instruction();
+	    return ir_call::get_error_instruction(ctx);
 	 }
       }
 
-      return ir_call::get_error_instruction();
+      return ir_call::get_error_instruction(ctx);
    } else {
       const ast_expression *id = subexpressions[0];
       YYLTYPE loc = id->get_location();
@@ -735,5 +747,5 @@
 				    &actual_parameters, state);
    }
 
-   return ir_call::get_error_instruction();
+   return ir_call::get_error_instruction(ctx);
 }
diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp
index 25bbe2f..33eb275 100644
--- a/ast_to_hir.cpp
+++ b/ast_to_hir.cpp
@@ -87,6 +87,7 @@
 apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from,
 			  struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
    if (to->base_type == from->type->base_type)
       return true;
 
@@ -111,13 +112,13 @@
 
    switch (from->type->base_type) {
    case GLSL_TYPE_INT:
-      from = new ir_expression(ir_unop_i2f, to, from, NULL);
+      from = new(ctx) ir_expression(ir_unop_i2f, to, from, NULL);
       break;
    case GLSL_TYPE_UINT:
-      from = new ir_expression(ir_unop_u2f, to, from, NULL);
+      from = new(ctx) ir_expression(ir_unop_u2f, to, from, NULL);
       break;
    case GLSL_TYPE_BOOL:
-      from = new ir_expression(ir_unop_b2f, to, from, NULL);
+      from = new(ctx) ir_expression(ir_unop_b2f, to, from, NULL);
       break;
    default:
       assert(0);
@@ -467,6 +468,7 @@
 	      ir_rvalue *lhs, ir_rvalue *rhs,
 	      YYLTYPE lhs_loc)
 {
+   void *ctx = talloc_parent(state);
    bool error_emitted = (lhs->type->is_error() || rhs->type->is_error());
 
    if (!error_emitted) {
@@ -504,7 +506,8 @@
 			     var->max_array_access);
 	 }
 
-	 var->type = glsl_type::get_array_instance(lhs->type->element_type(),
+	 var->type = glsl_type::get_array_instance(state,
+						   lhs->type->element_type(),
 						   rhs->type->array_size());
       }
    }
@@ -519,17 +522,19 @@
     * temporary and return a deref of that temporary.  If the rvalue
     * ends up not being used, the temp will get copy-propagated out.
     */
-   ir_variable *var = new ir_variable(rhs->type, "assignment_tmp");
+   ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp");
+   ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var);
    instructions->push_tail(var);
-   instructions->push_tail(new ir_assignment(new ir_dereference_variable(var),
-					     rhs,
-					     NULL));
+   instructions->push_tail(new(ctx) ir_assignment(deref_var,
+						  rhs,
+						  NULL));
+   deref_var = new(ctx) ir_dereference_variable(var);
 
-   instructions->push_tail(new ir_assignment(lhs,
-					     new ir_dereference_variable(var),
-					     NULL));
+   instructions->push_tail(new(ctx) ir_assignment(lhs,
+						  deref_var,
+						  NULL));
 
-   return new ir_dereference_variable(var);
+   return new(ctx) ir_dereference_variable(var);
 }
 
 
@@ -540,12 +545,13 @@
 generate_temporary(const glsl_type *type, exec_list *instructions,
 		   struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
    char *name = (char *) malloc(sizeof(char) * 13);
 
    snprintf(name, 13, "tmp_%08X", state->temp_index);
    state->temp_index++;
 
-   ir_variable *const var = new ir_variable(type, name);
+   ir_variable *const var = new(ctx) ir_variable(type, name);
    instructions->push_tail(var);
 
    return var;
@@ -555,21 +561,22 @@
 static ir_rvalue *
 get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue)
 {
+   void *ctx = talloc_parent(lvalue);
    ir_variable *var;
 
    /* FINISHME: Give unique names to the temporaries. */
-   var = new ir_variable(lvalue->type, "_post_incdec_tmp");
+   var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp");
    var->mode = ir_var_auto;
 
-   instructions->push_tail(new ir_assignment(new ir_dereference_variable(var),
-					     lvalue, NULL));
+   instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
+						  lvalue, NULL));
 
    /* Once we've created this temporary, mark it read only so it's no
     * longer considered an lvalue.
     */
    var->read_only = true;
 
-   return new ir_dereference_variable(var);
+   return new(ctx) ir_dereference_variable(var);
 }
 
 
@@ -588,6 +595,7 @@
 ast_expression::hir(exec_list *instructions,
 		    struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
    static const int operations[AST_NUM_OPERATORS] = {
       -1,               /* ast_assign doesn't convert to ir_expression. */
       -1,               /* ast_plus doesn't convert to ir_expression. */
@@ -680,8 +688,8 @@
 
       error_emitted = type->is_error();
 
-      result = new ir_expression(operations[this->oper], type,
-				 op[0], NULL);
+      result = new(ctx) ir_expression(operations[this->oper], type,
+				      op[0], NULL);
       break;
 
    case ast_add:
@@ -696,8 +704,8 @@
 				    state, & loc);
       error_emitted = type->is_error();
 
-      result = new ir_expression(operations[this->oper], type,
-				 op[0], op[1]);
+      result = new(ctx) ir_expression(operations[this->oper], type,
+				      op[0], op[1]);
       break;
 
    case ast_mod:
@@ -708,8 +716,8 @@
 
       assert(operations[this->oper] == ir_binop_mod);
 
-      result = new ir_expression(operations[this->oper], type,
-				 op[0], op[1]);
+      result = new(ctx) ir_expression(operations[this->oper], type,
+				      op[0], op[1]);
       error_emitted = type->is_error();
       break;
 
@@ -735,8 +743,8 @@
 	     || ((type->base_type == GLSL_TYPE_BOOL)
 		 && type->is_scalar()));
 
-      result = new ir_expression(operations[this->oper], type,
-				 op[0], op[1]);
+      result = new(ctx) ir_expression(operations[this->oper], type,
+				      op[0], op[1]);
       error_emitted = type->is_error();
       break;
 
@@ -767,8 +775,8 @@
 	 error_emitted = true;
       }
 
-      result = new ir_expression(operations[this->oper], glsl_type::bool_type,
-				 op[0], op[1]);
+      result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
+				      op[0], op[1]);
       type = glsl_type::bool_type;
 
       assert(result->type == glsl_type::bool_type);
@@ -812,7 +820,7 @@
 	 }
 	 type = glsl_type::bool_type;
       } else {
-	 ir_if *const stmt = new ir_if(op[0]);
+	 ir_if *const stmt = new(ctx) ir_if(op[0]);
 	 instructions->push_tail(stmt);
 
 	 op[1] = this->subexpressions[1]->hir(&stmt->then_instructions, state);
@@ -829,17 +837,17 @@
 	 ir_variable *const tmp = generate_temporary(glsl_type::bool_type,
 						     instructions, state);
 
-	 ir_dereference *const then_deref = new ir_dereference_variable(tmp);
+	 ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
 	 ir_assignment *const then_assign =
-	    new ir_assignment(then_deref, op[1], NULL);
+	    new(ctx) ir_assignment(then_deref, op[1], NULL);
 	 stmt->then_instructions.push_tail(then_assign);
 
-	 ir_dereference *const else_deref = new ir_dereference_variable(tmp);
+	 ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
 	 ir_assignment *const else_assign =
-	    new ir_assignment(else_deref, new ir_constant(false), NULL);
+	    new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false), NULL);
 	 stmt->else_instructions.push_tail(else_assign);
 
-	 result = new ir_dereference_variable(tmp);
+	 result = new(ctx) ir_dereference_variable(tmp);
 	 type = tmp->type;
       }
       break;
@@ -875,7 +883,7 @@
 	 }
 	 type = glsl_type::bool_type;
       } else {
-	 ir_if *const stmt = new ir_if(op[0]);
+	 ir_if *const stmt = new(ctx) ir_if(op[0]);
 	 instructions->push_tail(stmt);
 
 	 ir_variable *const tmp = generate_temporary(glsl_type::bool_type,
@@ -891,17 +899,17 @@
 	    error_emitted = true;
 	 }
 
-	 ir_dereference *const then_deref = new ir_dereference_variable(tmp);
+	 ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
 	 ir_assignment *const then_assign =
-	    new ir_assignment(then_deref, new ir_constant(true), NULL);
+	    new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true), NULL);
 	 stmt->then_instructions.push_tail(then_assign);
 
-	 ir_dereference *const else_deref = new ir_dereference_variable(tmp);
+	 ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
 	 ir_assignment *const else_assign =
-	    new ir_assignment(else_deref, op[1], NULL);
+	    new(ctx) ir_assignment(else_deref, op[1], NULL);
 	 stmt->else_instructions.push_tail(else_assign);
 
-	 result = new ir_dereference_variable(tmp);
+	 result = new(ctx) ir_dereference_variable(tmp);
 	 type = tmp->type;
       }
       break;
@@ -912,8 +920,8 @@
       op[1] = this->subexpressions[1]->hir(instructions, state);
 
 
-      result = new ir_expression(operations[this->oper], glsl_type::bool_type,
-				 op[0], op[1]);
+      result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
+				      op[0], op[1]);
       type = glsl_type::bool_type;
       break;
 
@@ -928,8 +936,8 @@
 	 error_emitted = true;
       }
 
-      result = new ir_expression(operations[this->oper], glsl_type::bool_type,
-				 op[0], NULL);
+      result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
+				      op[0], NULL);
       type = glsl_type::bool_type;
       break;
 
@@ -944,8 +952,8 @@
 				    (this->oper == ast_mul_assign),
 				    state, & loc);
 
-      ir_rvalue *temp_rhs = new ir_expression(operations[this->oper], type,
-				              op[0], op[1]);
+      ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+						   op[0], op[1]);
 
       result = do_assignment(instructions, state,
 			     (ir_rvalue *)op[0]->clone(NULL), temp_rhs,
@@ -970,8 +978,8 @@
       assert(operations[this->oper] == ir_binop_mod);
 
       struct ir_rvalue *temp_rhs;
-      temp_rhs = new ir_expression(operations[this->oper], type,
-				   op[0], op[1]);
+      temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+					op[0], op[1]);
 
       result = do_assignment(instructions, state,
 			     (ir_rvalue *)op[0]->clone(NULL), temp_rhs,
@@ -1057,22 +1065,24 @@
 	 ir_variable *const tmp = generate_temporary(type,
 						     instructions, state);
 
-	 ir_if *const stmt = new ir_if(op[0]);
+	 ir_if *const stmt = new(ctx) ir_if(op[0]);
 	 instructions->push_tail(stmt);
 
 	 then_instructions.move_nodes_to(& stmt->then_instructions);
-	 ir_dereference *const then_deref = new ir_dereference_variable(tmp);
+	 ir_dereference *const then_deref =
+	    new(ctx) ir_dereference_variable(tmp);
 	 ir_assignment *const then_assign =
-	    new ir_assignment(then_deref, op[1], NULL);
+	    new(ctx) ir_assignment(then_deref, op[1], NULL);
 	 stmt->then_instructions.push_tail(then_assign);
 
 	 else_instructions.move_nodes_to(& stmt->else_instructions);
-	 ir_dereference *const else_deref = new ir_dereference_variable(tmp);
+	 ir_dereference *const else_deref =
+	    new(ctx) ir_dereference_variable(tmp);
 	 ir_assignment *const else_assign =
-	    new ir_assignment(else_deref, op[2], NULL);
+	    new(ctx) ir_assignment(else_deref, op[2], NULL);
 	 stmt->else_instructions.push_tail(else_assign);
 
-	 result = new ir_dereference_variable(tmp);
+	 result = new(ctx) ir_dereference_variable(tmp);
       }
       break;
    }
@@ -1081,15 +1091,15 @@
    case ast_pre_dec: {
       op[0] = this->subexpressions[0]->hir(instructions, state);
       if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
-	 op[1] = new ir_constant(1.0f);
+	 op[1] = new(ctx) ir_constant(1.0f);
       else
-	 op[1] = new ir_constant(1);
+	 op[1] = new(ctx) ir_constant(1);
 
       type = arithmetic_result_type(op[0], op[1], false, state, & loc);
 
       struct ir_rvalue *temp_rhs;
-      temp_rhs = new ir_expression(operations[this->oper], type,
-				   op[0], op[1]);
+      temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+					op[0], op[1]);
 
       result = do_assignment(instructions, state,
 			     (ir_rvalue *)op[0]->clone(NULL), temp_rhs,
@@ -1103,17 +1113,17 @@
    case ast_post_dec: {
       op[0] = this->subexpressions[0]->hir(instructions, state);
       if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
-	 op[1] = new ir_constant(1.0f);
+	 op[1] = new(ctx) ir_constant(1.0f);
       else
-	 op[1] = new ir_constant(1);
+	 op[1] = new(ctx) ir_constant(1);
 
       error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
 
       type = arithmetic_result_type(op[0], op[1], false, state, & loc);
 
       struct ir_rvalue *temp_rhs;
-      temp_rhs = new ir_expression(operations[this->oper], type,
-				   op[0], op[1]);
+      temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+					op[0], op[1]);
 
       /* Get a temporary of a copy of the lvalue before it's modified.
        * This may get thrown away later.
@@ -1144,7 +1154,7 @@
 
       ir_rvalue *const array = op[0];
 
-      result = new ir_dereference_array(op[0], op[1]);
+      result = new(ctx) ir_dereference_array(op[0], op[1]);
 
       /* Do not use op[0] after this point.  Use array.
        */
@@ -1260,7 +1270,7 @@
       ir_variable *var = 
 	 state->symbols->get_variable(this->primary_expression.identifier);
 
-      result = new ir_dereference_variable(var);
+      result = new(ctx) ir_dereference_variable(var);
 
       if (var != NULL) {
 	 type = result->type;
@@ -1275,22 +1285,22 @@
 
    case ast_int_constant:
       type = glsl_type::int_type;
-      result = new ir_constant(this->primary_expression.int_constant);
+      result = new(ctx) ir_constant(this->primary_expression.int_constant);
       break;
 
    case ast_uint_constant:
       type = glsl_type::uint_type;
-      result = new ir_constant(this->primary_expression.uint_constant);
+      result = new(ctx) ir_constant(this->primary_expression.uint_constant);
       break;
 
    case ast_float_constant:
       type = glsl_type::float_type;
-      result = new ir_constant(this->primary_expression.float_constant);
+      result = new(ctx) ir_constant(this->primary_expression.float_constant);
       break;
 
    case ast_bool_constant:
       type = glsl_type::bool_type;
-      result = new ir_constant(bool(this->primary_expression.bool_constant));
+      result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant));
       break;
 
    case ast_sequence: {
@@ -1403,7 +1413,7 @@
       }
    }
 
-   return glsl_type::get_array_instance(base, length);
+   return glsl_type::get_array_instance(state, base, length);
 }
 
 
@@ -1529,6 +1539,7 @@
 ast_declarator_list::hir(exec_list *instructions,
 			 struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
    const struct glsl_type *decl_type;
    const char *type_name = NULL;
    ir_rvalue *result = NULL;
@@ -1589,7 +1600,7 @@
 	 var_type = decl_type;
       }
 
-      var = new ir_variable(var_type, decl->identifier);
+      var = new(ctx) ir_variable(var_type, decl->identifier);
 
       /* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification;
        *
@@ -1789,7 +1800,7 @@
 			     ? "attribute" : "varying");
 	 }
 
-	 ir_dereference *const lhs = new ir_dereference_variable(var);
+	 ir_dereference *const lhs = new(ctx) ir_dereference_variable(var);
 	 ir_rvalue *rhs = decl->initializer->hir(instructions, state);
 
 	 /* Calculate the constant value if this is a const or uniform
@@ -1867,6 +1878,7 @@
 ast_parameter_declarator::hir(exec_list *instructions,
 			      struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
    const struct glsl_type *type;
    const char *name = NULL;
    YYLTYPE loc = this->get_location();
@@ -1914,7 +1926,7 @@
    }
 
    is_void = false;
-   ir_variable *var = new ir_variable(type, this->identifier);
+   ir_variable *var = new(ctx) ir_variable(type, this->identifier);
 
    /* FINISHME: Handle array declarations.  Note that this requires
     * FINISHME: complete handling of constant expressions.
@@ -1967,6 +1979,7 @@
 ast_function::hir(exec_list *instructions,
 		  struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
    ir_function *f = NULL;
    ir_function_signature *sig = NULL;
    exec_list hir_parameters;
@@ -2026,7 +2039,7 @@
 		       "non-function", name);
       sig = NULL;
    } else {
-      f = new ir_function(name);
+      f = new(ctx) ir_function(name);
       state->symbols->add_function(f->name, f);
 
       /* Emit the new function header */
@@ -2051,7 +2064,7 @@
    /* Finish storing the information about this new function in its signature.
     */
    if (sig == NULL) {
-      sig = new ir_function_signature(return_type);
+      sig = new(ctx) ir_function_signature(return_type);
       f->add_signature(sig);
    }
 
@@ -2116,6 +2129,7 @@
 ast_jump_statement::hir(exec_list *instructions,
 			struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
 
    switch (mode) {
    case ast_return: {
@@ -2141,7 +2155,7 @@
 	  * FINISHME: type of the enclosing function.
 	  */
 
-	 inst = new ir_return(ret);
+	 inst = new(ctx) ir_return(ret);
       } else {
 	 if (state->current_function->return_type->base_type !=
 	     GLSL_TYPE_VOID) {
@@ -2152,7 +2166,7 @@
 			     "non-void",
 			     state->current_function->function_name());
 	 }
-	 inst = new ir_return;
+	 inst = new(ctx) ir_return;
       }
 
       instructions->push_tail(inst);
@@ -2189,9 +2203,9 @@
 
 	 if (loop != NULL) {
 	    ir_loop_jump *const jump =
-	       new ir_loop_jump((mode == ast_break)
-				? ir_loop_jump::jump_break
-				: ir_loop_jump::jump_continue);
+	       new(ctx) ir_loop_jump((mode == ast_break)
+				     ? ir_loop_jump::jump_break
+				     : ir_loop_jump::jump_continue);
 	    instructions->push_tail(jump);
 	 }
       }
@@ -2209,6 +2223,8 @@
 ast_selection_statement::hir(exec_list *instructions,
 			     struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
+
    ir_rvalue *const condition = this->condition->hir(instructions, state);
 
    /* From page 66 (page 72 of the PDF) of the GLSL 1.50 spec:
@@ -2227,7 +2243,7 @@
 		       "boolean");
    }
 
-   ir_if *const stmt = new ir_if(condition);
+   ir_if *const stmt = new(ctx) ir_if(condition);
 
    if (then_statement != NULL)
       then_statement->hir(& stmt->then_instructions, state);
@@ -2247,6 +2263,8 @@
 ast_iteration_statement::condition_to_hir(ir_loop *stmt,
 					  struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
+
    if (condition != NULL) {
       ir_rvalue *const cond =
 	 condition->hir(& stmt->body_instructions, state);
@@ -2262,13 +2280,13 @@
 	  * like 'if (!condition) break;' as the loop termination condition.
 	  */
 	 ir_rvalue *const not_cond =
-	    new ir_expression(ir_unop_logic_not, glsl_type::bool_type, cond,
-			      NULL);
+	    new(ctx) ir_expression(ir_unop_logic_not, glsl_type::bool_type, cond,
+				   NULL);
 
-	 ir_if *const if_stmt = new ir_if(not_cond);
+	 ir_if *const if_stmt = new(ctx) ir_if(not_cond);
 
 	 ir_jump *const break_stmt =
-	    new ir_loop_jump(ir_loop_jump::jump_break);
+	    new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
 
 	 if_stmt->then_instructions.push_tail(break_stmt);
 	 stmt->body_instructions.push_tail(if_stmt);
@@ -2281,6 +2299,8 @@
 ast_iteration_statement::hir(exec_list *instructions,
 			     struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
+
    /* For-loops and while-loops start a new scope, but do-while loops do not.
     */
    if (mode != ast_do_while)
@@ -2289,7 +2309,7 @@
    if (init_statement != NULL)
       init_statement->hir(instructions, state);
 
-   ir_loop *const stmt = new ir_loop();
+   ir_loop *const stmt = new(ctx) ir_loop();
    instructions->push_tail(stmt);
 
    /* Track the current loop and / or switch-statement nesting.
@@ -2337,6 +2357,7 @@
 ast_struct_specifier::hir(exec_list *instructions,
 			  struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
    unsigned decl_count = 0;
 
    /* Make an initial pass over the list of structure fields to determine how
@@ -2399,7 +2420,7 @@
       name = this->name;
    }
 
-   glsl_type *t = new glsl_type(fields, decl_count, name);
+   glsl_type *t = new(ctx) glsl_type(fields, decl_count, name);
 
    YYLTYPE loc = this->get_location();
    if (!state->symbols->add_type(name, t)) {
diff --git a/glsl_lexer.lpp b/glsl_lexer.lpp
index c15c99c..fa439f1 100644
--- a/glsl_lexer.lpp
+++ b/glsl_lexer.lpp
@@ -312,7 +312,9 @@
 precision	return PRECISION;
 
 [_a-zA-Z][_a-zA-Z0-9]*	{
-			    yylval->identifier = strdup(yytext);
+			    struct _mesa_glsl_parse_state *state = yyextra;
+			    void *ctx = talloc_parent(state);	
+			    yylval->identifier = talloc_strdup(ctx, yytext);
 			    return IDENTIFIER;
 			}
 
diff --git a/glsl_parser.ypp b/glsl_parser.ypp
index ae009ed..4132495 100644
--- a/glsl_parser.ypp
+++ b/glsl_parser.ypp
@@ -255,31 +255,36 @@
 primary_expression:
 	variable_identifier
 	{
-	   $$ = new ast_expression(ast_identifier, NULL, NULL, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL);
 	   $$->set_location(yylloc);
 	   $$->primary_expression.identifier = $1;
 	}
 	| INTCONSTANT
 	{
-	   $$ = new ast_expression(ast_int_constant, NULL, NULL, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL);
 	   $$->set_location(yylloc);
 	   $$->primary_expression.int_constant = $1;
 	}
 	| UINTCONSTANT
 	{
-	   $$ = new ast_expression(ast_uint_constant, NULL, NULL, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL);
 	   $$->set_location(yylloc);
 	   $$->primary_expression.uint_constant = $1;
 	}
 	| FLOATCONSTANT
 	{
-	   $$ = new ast_expression(ast_float_constant, NULL, NULL, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL);
 	   $$->set_location(yylloc);
 	   $$->primary_expression.float_constant = $1;
 	}
 	| BOOLCONSTANT
 	{
-	   $$ = new ast_expression(ast_bool_constant, NULL, NULL, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL);
 	   $$->set_location(yylloc);
 	   $$->primary_expression.bool_constant = $1;
 	}
@@ -293,7 +298,8 @@
 	primary_expression
 	| postfix_expression '[' integer_expression ']'
 	{
-	   $$ = new ast_expression(ast_array_index, $1, $3, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression(ast_array_index, $1, $3, NULL);
 	   $$->set_location(yylloc);
 	}
 	| function_call
@@ -308,18 +314,21 @@
 	}
 	| postfix_expression '.' IDENTIFIER
 	{
-	   $$ = new ast_expression(ast_field_selection, $1, NULL, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression(ast_field_selection, $1, NULL, NULL);
 	   $$->set_location(yylloc);
 	   $$->primary_expression.identifier = $3;
 	}
 	| postfix_expression INC_OP
 	{
-	   $$ = new ast_expression(ast_post_inc, $1, NULL, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression(ast_post_inc, $1, NULL, NULL);
 	   $$->set_location(yylloc);
 	}
 	| postfix_expression DEC_OP
 	{
-	   $$ = new ast_expression(ast_post_dec, $1, NULL, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression(ast_post_dec, $1, NULL, NULL);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -336,7 +345,8 @@
 	function_call_generic
 	| postfix_expression '.' function_call_generic
 	{
-	   $$ = new ast_expression(ast_field_selection, $1, $3, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression(ast_field_selection, $1, $3, NULL);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -376,19 +386,22 @@
 function_identifier:
 	type_specifier
 	{
-	   $$ = new ast_function_expression($1);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_function_expression($1);
 	   $$->set_location(yylloc);
    	}
 	| IDENTIFIER
 	{
-	   ast_expression *callee = new ast_expression($1);
-	   $$ = new ast_function_expression(callee);
+	   void *ctx = talloc_parent(state);
+	   ast_expression *callee = new(ctx) ast_expression($1);
+	   $$ = new(ctx) ast_function_expression(callee);
 	   $$->set_location(yylloc);
    	}
 	| FIELD_SELECTION
 	{
-	   ast_expression *callee = new ast_expression($1);
-	   $$ = new ast_function_expression(callee);
+	   void *ctx = talloc_parent(state);
+	   ast_expression *callee = new(ctx) ast_expression($1);
+	   $$ = new(ctx) ast_function_expression(callee);
 	   $$->set_location(yylloc);
    	}
 	;
@@ -398,17 +411,20 @@
 	postfix_expression
 	| INC_OP unary_expression
 	{
-	   $$ = new ast_expression(ast_pre_inc, $2, NULL, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression(ast_pre_inc, $2, NULL, NULL);
 	   $$->set_location(yylloc);
 	}
 	| DEC_OP unary_expression
 	{
-	   $$ = new ast_expression(ast_pre_dec, $2, NULL, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression(ast_pre_dec, $2, NULL, NULL);
 	   $$->set_location(yylloc);
 	}
 	| unary_operator unary_expression
 	{
-	   $$ = new ast_expression($1, $2, NULL, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression($1, $2, NULL, NULL);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -425,17 +441,20 @@
 	unary_expression
 	| multiplicative_expression '*' unary_expression
 	{
-	   $$ = new ast_expression_bin(ast_mul, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_mul, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	| multiplicative_expression '/' unary_expression
 	{
-	   $$ = new ast_expression_bin(ast_div, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_div, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	| multiplicative_expression '%' unary_expression
 	{
-	   $$ = new ast_expression_bin(ast_mod, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_mod, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -444,12 +463,14 @@
 	multiplicative_expression
 	| additive_expression '+' multiplicative_expression
 	{
-	   $$ = new ast_expression_bin(ast_add, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_add, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	| additive_expression '-' multiplicative_expression
 	{
-	   $$ = new ast_expression_bin(ast_sub, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_sub, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -458,12 +479,14 @@
 	additive_expression
 	| shift_expression LEFT_OP additive_expression
 	{
-	   $$ = new ast_expression_bin(ast_lshift, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_lshift, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	| shift_expression RIGHT_OP additive_expression
 	{
-	   $$ = new ast_expression_bin(ast_rshift, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_rshift, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -472,22 +495,26 @@
 	shift_expression
 	| relational_expression '<' shift_expression
 	{
-	   $$ = new ast_expression_bin(ast_less, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_less, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	| relational_expression '>' shift_expression
 	{
-	   $$ = new ast_expression_bin(ast_greater, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_greater, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	| relational_expression LE_OP shift_expression
 	{
-	   $$ = new ast_expression_bin(ast_lequal, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_lequal, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	| relational_expression GE_OP shift_expression
 	{
-	   $$ = new ast_expression_bin(ast_gequal, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_gequal, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -496,12 +523,14 @@
 	relational_expression
 	| equality_expression EQ_OP relational_expression
 	{
-	   $$ = new ast_expression_bin(ast_equal, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_equal, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	| equality_expression NE_OP relational_expression
 	{
-	   $$ = new ast_expression_bin(ast_nequal, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_nequal, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -510,7 +539,8 @@
 	equality_expression
 	| and_expression '&' equality_expression
 	{
-	   $$ = new ast_expression_bin(ast_bit_or, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -519,7 +549,8 @@
 	and_expression
 	| exclusive_or_expression '^' and_expression
 	{
-	   $$ = new ast_expression_bin(ast_bit_xor, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_bit_xor, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -528,7 +559,8 @@
 	exclusive_or_expression
 	| inclusive_or_expression '|' exclusive_or_expression
 	{
-	   $$ = new ast_expression_bin(ast_bit_or, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -537,7 +569,8 @@
 	inclusive_or_expression
 	| logical_and_expression AND_OP inclusive_or_expression
 	{
-	   $$ = new ast_expression_bin(ast_logic_and, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_logic_and, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -546,7 +579,8 @@
 	logical_and_expression
 	| logical_xor_expression XOR_OP logical_and_expression
 	{
-	   $$ = new ast_expression_bin(ast_logic_xor, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_logic_xor, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -555,7 +589,8 @@
 	logical_xor_expression
 	| logical_or_expression OR_OP logical_xor_expression
 	{
-	   $$ = new ast_expression_bin(ast_logic_or, $1, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_bin(ast_logic_or, $1, $3);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -564,7 +599,8 @@
 	logical_or_expression
 	| logical_or_expression '?' expression ':' assignment_expression
 	{
-	   $$ = new ast_expression(ast_conditional, $1, $3, $5);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression(ast_conditional, $1, $3, $5);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -573,7 +609,8 @@
 	conditional_expression
 	| unary_expression assignment_operator assignment_expression
 	{
-	   $$ = new ast_expression($2, $1, $3, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression($2, $1, $3, NULL);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -599,8 +636,9 @@
 	}
 	| expression ',' assignment_expression
 	{
+	   void *ctx = talloc_parent(state);
 	   if ($1->oper != ast_sequence) {
-	      $$ = new ast_expression(ast_sequence, NULL, NULL, NULL);
+	      $$ = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL);
 	      $$->set_location(yylloc);
 	      $$->expressions.push_tail(& $1->link);
 	   } else {
@@ -662,7 +700,8 @@
 function_header:
 	fully_specified_type IDENTIFIER '('
 	{
-	   $$ = new ast_function();
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_function();
 	   $$->set_location(yylloc);
 	   $$->return_type = $1;
 	   $$->identifier = $2;
@@ -672,18 +711,20 @@
 parameter_declarator:
 	type_specifier IDENTIFIER
 	{
-	   $$ = new ast_parameter_declarator();
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_parameter_declarator();
 	   $$->set_location(yylloc);
-	   $$->type = new ast_fully_specified_type();
+	   $$->type = new(ctx) ast_fully_specified_type();
 	   $$->type->set_location(yylloc);
 	   $$->type->specifier = $1;
 	   $$->identifier = $2;
 	}
 	| type_specifier IDENTIFIER '[' constant_expression ']'
 	{
-	   $$ = new ast_parameter_declarator();
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_parameter_declarator();
 	   $$->set_location(yylloc);
-	   $$->type = new ast_fully_specified_type();
+	   $$->type = new(ctx) ast_fully_specified_type();
 	   $$->type->set_location(yylloc);
 	   $$->type->specifier = $1;
 	   $$->identifier = $2;
@@ -707,19 +748,21 @@
 	}
 	| parameter_type_qualifier parameter_qualifier parameter_type_specifier
 	{
+	   void *ctx = talloc_parent(state);
 	   $1.i |= $2.i;
 
-	   $$ = new ast_parameter_declarator();
+	   $$ = new(ctx) ast_parameter_declarator();
 	   $$->set_location(yylloc);
-	   $$->type = new ast_fully_specified_type();
+	   $$->type = new(ctx) ast_fully_specified_type();
 	   $$->type->qualifier = $1.q;
 	   $$->type->specifier = $3;
 	}
 	| parameter_qualifier parameter_type_specifier
 	{
-	   $$ = new ast_parameter_declarator();
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_parameter_declarator();
 	   $$->set_location(yylloc);
-	   $$->type = new ast_fully_specified_type();
+	   $$->type = new(ctx) ast_fully_specified_type();
 	   $$->type->qualifier = $1.q;
 	   $$->type->specifier = $2;
 	}
@@ -740,7 +783,8 @@
 	single_declaration
 	| init_declarator_list ',' IDENTIFIER
 	{
-	   ast_declaration *decl = new ast_declaration($3, false, NULL, NULL);
+	   void *ctx = talloc_parent(state);
+	   ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, NULL);
 	   decl->set_location(yylloc);
 
 	   $$ = $1;
@@ -748,7 +792,8 @@
 	}
 	| init_declarator_list ',' IDENTIFIER '[' ']'
 	{
-	   ast_declaration *decl = new ast_declaration($3, true, NULL, NULL);
+	   void *ctx = talloc_parent(state);
+	   ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, NULL);
 	   decl->set_location(yylloc);
 
 	   $$ = $1;
@@ -756,7 +801,8 @@
 	}
 	| init_declarator_list ',' IDENTIFIER '[' constant_expression ']'
 	{
-	   ast_declaration *decl = new ast_declaration($3, true, $5, NULL);
+	   void *ctx = talloc_parent(state);
+	   ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, NULL);
 	   decl->set_location(yylloc);
 
 	   $$ = $1;
@@ -764,7 +810,8 @@
 	}
 	| init_declarator_list ',' IDENTIFIER '[' ']' '=' initializer
 	{
-	   ast_declaration *decl = new ast_declaration($3, true, NULL, $7);
+	   void *ctx = talloc_parent(state);
+	   ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, $7);
 	   decl->set_location(yylloc);
 
 	   $$ = $1;
@@ -772,7 +819,8 @@
 	}
 	| init_declarator_list ',' IDENTIFIER '[' constant_expression ']' '=' initializer
 	{
-	   ast_declaration *decl = new ast_declaration($3, true, $5, $8);
+	   void *ctx = talloc_parent(state);
+	   ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, $8);
 	   decl->set_location(yylloc);
 
 	   $$ = $1;
@@ -780,7 +828,8 @@
 	}
 	| init_declarator_list ',' IDENTIFIER '=' initializer
 	{
-	   ast_declaration *decl = new ast_declaration($3, false, NULL, $5);
+	   void *ctx = talloc_parent(state);
+	   ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, $5);
 	   decl->set_location(yylloc);
 
 	   $$ = $1;
@@ -792,67 +841,75 @@
 single_declaration:
 	fully_specified_type
 	{
+	   void *ctx = talloc_parent(state);
 	   if ($1->specifier->type_specifier != ast_struct) {
 	      _mesa_glsl_error(& @1, state, "empty declaration list\n");
 	      YYERROR;
 	   } else {
-	      $$ = new ast_declarator_list($1);
+	      $$ = new(ctx) ast_declarator_list($1);
 	      $$->set_location(yylloc);
 	   }
 	}
 	| fully_specified_type IDENTIFIER
 	{
-	   ast_declaration *decl = new ast_declaration($2, false, NULL, NULL);
+	   void *ctx = talloc_parent(state);
+	   ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL);
 
-	   $$ = new ast_declarator_list($1);
+	   $$ = new(ctx) ast_declarator_list($1);
 	   $$->set_location(yylloc);
 	   $$->declarations.push_tail(&decl->link);
 	}
 	| fully_specified_type IDENTIFIER '[' ']'
 	{
-	   ast_declaration *decl = new ast_declaration($2, true, NULL, NULL);
+	   void *ctx = talloc_parent(state);
+	   ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, NULL);
 
-	   $$ = new ast_declarator_list($1);
+	   $$ = new(ctx) ast_declarator_list($1);
 	   $$->set_location(yylloc);
 	   $$->declarations.push_tail(&decl->link);
 	}
 	| fully_specified_type IDENTIFIER '[' constant_expression ']'
 	{
-	   ast_declaration *decl = new ast_declaration($2, true, $4, NULL);
+	   void *ctx = talloc_parent(state);
+	   ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, NULL);
 
-	   $$ = new ast_declarator_list($1);
+	   $$ = new(ctx) ast_declarator_list($1);
 	   $$->set_location(yylloc);
 	   $$->declarations.push_tail(&decl->link);
 	}
 	| fully_specified_type IDENTIFIER '[' ']' '=' initializer
 	{
-	   ast_declaration *decl = new ast_declaration($2, true, NULL, $6);
+	   void *ctx = talloc_parent(state);
+	   ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, $6);
 
-	   $$ = new ast_declarator_list($1);
+	   $$ = new(ctx) ast_declarator_list($1);
 	   $$->set_location(yylloc);
 	   $$->declarations.push_tail(&decl->link);
 	}
 	| fully_specified_type IDENTIFIER '[' constant_expression ']' '=' initializer
 	{
-	   ast_declaration *decl = new ast_declaration($2, true, $4, $7);
+	   void *ctx = talloc_parent(state);
+	   ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, $7);
 
-	   $$ = new ast_declarator_list($1);
+	   $$ = new(ctx) ast_declarator_list($1);
 	   $$->set_location(yylloc);
 	   $$->declarations.push_tail(&decl->link);
 	}
 	| fully_specified_type IDENTIFIER '=' initializer
 	{
-	   ast_declaration *decl = new ast_declaration($2, false, NULL, $4);
+	   void *ctx = talloc_parent(state);
+	   ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4);
 
-	   $$ = new ast_declarator_list($1);
+	   $$ = new(ctx) ast_declarator_list($1);
 	   $$->set_location(yylloc);
 	   $$->declarations.push_tail(&decl->link);
 	}
 	| INVARIANT IDENTIFIER // Vertex only.
 	{
-	   ast_declaration *decl = new ast_declaration($2, false, NULL, NULL);
+	   void *ctx = talloc_parent(state);
+	   ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL);
 
-	   $$ = new ast_declarator_list(NULL);
+	   $$ = new(ctx) ast_declarator_list(NULL);
 	   $$->set_location(yylloc);
 	   $$->invariant = true;
 
@@ -863,13 +920,15 @@
 fully_specified_type:
 	type_specifier
 	{
-	   $$ = new ast_fully_specified_type();
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_fully_specified_type();
 	   $$->set_location(yylloc);
 	   $$->specifier = $1;
 	}
 	| type_qualifier type_specifier
 	{
-	   $$ = new ast_fully_specified_type();
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_fully_specified_type();
 	   $$->set_location(yylloc);
 	   $$->qualifier = $1.q;
 	   $$->specifier = $2;
@@ -939,17 +998,20 @@
 type_specifier_nonarray:
 	basic_type_specifier_nonarray
 	{
-	   $$ = new ast_type_specifier($1);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_type_specifier($1);
 	   $$->set_location(yylloc);
 	}
 	| struct_specifier
 	{
-	   $$ = new ast_type_specifier($1);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_type_specifier($1);
 	   $$->set_location(yylloc);
 	}
 	| IDENTIFIER
 	{
-	   $$ = new ast_type_specifier($1);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_type_specifier($1);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -1050,12 +1112,14 @@
 struct_specifier:
 	STRUCT IDENTIFIER '{' struct_declaration_list '}'
 	{
-	   $$ = new ast_struct_specifier($2, $4);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_struct_specifier($2, $4);
 	   $$->set_location(yylloc);
 	}
 	| STRUCT '{' struct_declaration_list '}'
 	{
-	   $$ = new ast_struct_specifier(NULL, $3);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_struct_specifier(NULL, $3);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -1076,11 +1140,12 @@
 struct_declaration:
 	type_specifier struct_declarator_list ';'
 	{
-	   ast_fully_specified_type *type = new ast_fully_specified_type();
+	   void *ctx = talloc_parent(state);
+	   ast_fully_specified_type *type = new(ctx) ast_fully_specified_type();
 	   type->set_location(yylloc);
 
 	   type->specifier = $1;
-	   $$ = new ast_declarator_list(type);
+	   $$ = new(ctx) ast_declarator_list(type);
 	   $$->set_location(yylloc);
 
 	   $$->declarations.push_degenerate_list_at_head(& $2->link);
@@ -1103,12 +1168,14 @@
 struct_declarator:
 	IDENTIFIER
 	{
-	   $$ = new ast_declaration($1, false, NULL, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_declaration($1, false, NULL, NULL);
 	   $$->set_location(yylloc);
 	}
 	| IDENTIFIER '[' constant_expression ']'
 	{
-	   $$ = new ast_declaration($1, true, $3, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_declaration($1, true, $3, NULL);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -1150,12 +1217,14 @@
 compound_statement:
 	'{' '}'
 	{
-	   $$ = new ast_compound_statement(true, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_compound_statement(true, NULL);
 	   $$->set_location(yylloc);
 	}
 	| '{' statement_list '}'
 	{
-	   $$ = new ast_compound_statement(true, $2);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_compound_statement(true, $2);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -1168,12 +1237,14 @@
 compound_statement_no_new_scope:
 	'{' '}'
 	{
-	   $$ = new ast_compound_statement(false, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_compound_statement(false, NULL);
 	   $$->set_location(yylloc);
 	}
 	| '{' statement_list '}'
 	{
-	   $$ = new ast_compound_statement(false, $2);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_compound_statement(false, $2);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -1203,12 +1274,14 @@
 expression_statement:
 	';'
 	{
-	   $$ = new ast_expression_statement(NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_statement(NULL);
 	   $$->set_location(yylloc);
 	}
 	| expression ';'
 	{
-	   $$ = new ast_expression_statement($1);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_expression_statement($1);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -1216,7 +1289,8 @@
 selection_statement_matched:
 	IF '(' expression ')' statement_matched ELSE statement_matched
 	{
-	   $$ = new ast_selection_statement($3, $5, $7);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_selection_statement($3, $5, $7);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -1224,17 +1298,20 @@
 selection_statement_unmatched:
 	IF '(' expression ')' statement_matched
 	{
-	   $$ = new ast_selection_statement($3, $5, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_selection_statement($3, $5, NULL);
 	   $$->set_location(yylloc);
 	}
 	| IF '(' expression ')' statement_unmatched
 	{
-	   $$ = new ast_selection_statement($3, $5, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_selection_statement($3, $5, NULL);
 	   $$->set_location(yylloc);
 	}
 	| IF '(' expression ')' statement_matched ELSE statement_unmatched
 	{
-	   $$ = new ast_selection_statement($3, $5, $7);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_selection_statement($3, $5, $7);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -1246,8 +1323,9 @@
 	}
 	| fully_specified_type IDENTIFIER '=' initializer
 	{
-	   ast_declaration *decl = new ast_declaration($2, false, NULL, $4);
-	   ast_declarator_list *declarator = new ast_declarator_list($1);
+	   void *ctx = talloc_parent(state);
+	   ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4);
+	   ast_declarator_list *declarator = new(ctx) ast_declarator_list($1);
 	   decl->set_location(yylloc);
 	   declarator->set_location(yylloc);
 
@@ -1268,20 +1346,23 @@
 iteration_statement:
 	WHILE '(' condition ')' statement_no_new_scope
 	{
-	   $$ = new ast_iteration_statement(ast_iteration_statement::ast_while,
-					    NULL, $3, NULL, $5);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while,
+	   					    NULL, $3, NULL, $5);
 	   $$->set_location(yylloc);
 	}
 	| DO statement WHILE '(' expression ')' ';'
 	{
-	   $$ = new ast_iteration_statement(ast_iteration_statement::ast_do_while,
-					    NULL, $5, NULL, $2);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while,
+						    NULL, $5, NULL, $2);
 	   $$->set_location(yylloc);
 	}
 	| FOR '(' for_init_statement for_rest_statement ')' statement_no_new_scope
 	{
-	   $$ = new ast_iteration_statement(ast_iteration_statement::ast_for,
-					    $3, $4.cond, $4.rest, $6);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for,
+						    $3, $4.cond, $4.rest, $6);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -1316,27 +1397,32 @@
 jump_statement:
 	CONTINUE ';' 
 	{
-	   $$ = new ast_jump_statement(ast_jump_statement::ast_continue, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL);
 	   $$->set_location(yylloc);
 	}
 	| BREAK ';'
 	{
-	   $$ = new ast_jump_statement(ast_jump_statement::ast_break, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL);
 	   $$->set_location(yylloc);
 	}
 	| RETURN ';'
 	{
-	   $$ = new ast_jump_statement(ast_jump_statement::ast_return, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL);
 	   $$->set_location(yylloc);
 	}
 	| RETURN expression ';'
 	{
-	   $$ = new ast_jump_statement(ast_jump_statement::ast_return, $2);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, $2);
 	   $$->set_location(yylloc);
 	}
 	| DISCARD ';' // Fragment shader only.
 	{
-	   $$ = new ast_jump_statement(ast_jump_statement::ast_discard, NULL);
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL);
 	   $$->set_location(yylloc);
 	}
 	;
@@ -1349,7 +1435,8 @@
 function_definition:
 	function_prototype compound_statement_no_new_scope
 	{
-	   $$ = new ast_function_definition();
+	   void *ctx = talloc_parent(state);
+	   $$ = new(ctx) ast_function_definition();
 	   $$->set_location(yylloc);
 	   $$->prototype = $1;
 	   $$->body = $2;
diff --git a/glsl_symbol_table.h b/glsl_symbol_table.h
index 26b90fd..ae2fd3f 100644
--- a/glsl_symbol_table.h
+++ b/glsl_symbol_table.h
@@ -26,6 +26,8 @@
 #ifndef GLSL_SYMBOL_TABLE
 #define GLSL_SYMBOL_TABLE
 
+#include <new>
+
 #include "symbol_table.h"
 #include "ir.h"
 #include "glsl_types.h"
@@ -44,7 +46,38 @@
       glsl_function_name_space = 2
    };
 
+   static int
+   _glsl_symbol_table_destructor (glsl_symbol_table *table)
+   {
+      table->~glsl_symbol_table();
+
+      return 0;
+   }
+
 public:
+   /* Callers of this talloc-based new need not call delete. It's
+    * easier to just talloc_free 'ctx' (or any of its ancestors). */
+   static void* operator new(size_t size, void *ctx)
+   {
+      void *table;
+
+      table = talloc_size(ctx, size);
+      assert(table != NULL);
+
+      talloc_set_destructor(table, (int (*)(void*)) _glsl_symbol_table_destructor);
+
+      return table;
+   }
+
+   /* If the user *does* call delete, that's OK, we will just
+    * talloc_free in that case. Here, C++ will have already called the
+    * destructor so tell talloc not to do that again. */
+   static void operator delete(void *table)
+   {
+      talloc_set_destructor(table, NULL);
+      talloc_free(table);
+   }
+   
    glsl_symbol_table()
    {
       table = _mesa_symbol_table_ctor();
diff --git a/glsl_types.cpp b/glsl_types.cpp
index ca19de6..bef267f 100644
--- a/glsl_types.cpp
+++ b/glsl_types.cpp
@@ -150,14 +150,16 @@
 ir_function *
 glsl_type::generate_constructor(glsl_symbol_table *symtab) const
 {
+   void *ctx = symtab;
+
    /* Generate the function name and add it to the symbol table.
     */
-   ir_function *const f = new ir_function(name);
+   ir_function *const f = new(ctx) ir_function(name);
 
    bool added = symtab->add_function(name, f);
    assert(added);
 
-   ir_function_signature *const sig = new ir_function_signature(this);
+   ir_function_signature *const sig = new(ctx) ir_function_signature(this);
    f->add_signature(sig);
 
    ir_variable **declarations =
@@ -168,8 +170,8 @@
       snprintf(param_name, 10, "p%08X", i);
 
       ir_variable *var = (this->base_type == GLSL_TYPE_ARRAY)
-	 ? new ir_variable(fields.array, param_name)
-	 : new ir_variable(fields.structure[i].type, param_name);
+	 ? new(ctx) ir_variable(fields.array, param_name)
+	 : new(ctx) ir_variable(fields.structure[i].type, param_name);
 
       var->mode = ir_var_in;
       declarations[i] = var;
@@ -181,24 +183,26 @@
     * the same type as the constructor.  After initializing __retval,
     * __retval is returned.
     */
-   ir_variable *retval = new ir_variable(this, "__retval");
+   ir_variable *retval = new(ctx) ir_variable(this, "__retval");
    sig->body.push_tail(retval);
 
    for (unsigned i = 0; i < length; i++) {
       ir_dereference *const lhs = (this->base_type == GLSL_TYPE_ARRAY)
-	 ? (ir_dereference *) new ir_dereference_array(retval, new ir_constant(i))
-	 : (ir_dereference *) new ir_dereference_record(retval, fields.structure[i].name);
+	 ? (ir_dereference *) new(ctx) ir_dereference_array(retval,
+							    new(ctx) ir_constant(i))
+	 : (ir_dereference *) new(ctx) ir_dereference_record(retval,
+							     fields.structure[i].name);
 
-      ir_dereference *const rhs = new ir_dereference_variable(declarations[i]);
-      ir_instruction *const assign = new ir_assignment(lhs, rhs, NULL);
+      ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[i]);
+      ir_instruction *const assign = new(ctx) ir_assignment(lhs, rhs, NULL);
 
       sig->body.push_tail(assign);
    }
 
    free(declarations);
 
-   ir_dereference *const retref = new ir_dereference_variable(retval);
-   ir_instruction *const inst = new ir_return(retref);
+   ir_dereference *const retref = new(ctx) ir_dereference_variable(retval);
+   ir_instruction *const inst = new(ctx) ir_return(retref);
    sig->body.push_tail(inst);
 
    return f;
@@ -220,7 +224,8 @@
  *                     the symbol table.
  */
 static ir_function_signature *
-generate_constructor_intro(const glsl_type *type, unsigned parameter_count,
+generate_constructor_intro(void *ctx,
+			   const glsl_type *type, unsigned parameter_count,
 			   ir_variable **declarations)
 {
    /* Names of parameters used in vector and matrix constructors
@@ -234,10 +239,10 @@
 
    const glsl_type *const parameter_type = type->get_base_type();
 
-   ir_function_signature *const signature = new ir_function_signature(type);
+   ir_function_signature *const signature = new(ctx) ir_function_signature(type);
 
    for (unsigned i = 0; i < parameter_count; i++) {
-      ir_variable *var = new ir_variable(parameter_type, names[i]);
+      ir_variable *var = new(ctx) ir_variable(parameter_type, names[i]);
 
       var->mode = ir_var_in;
       signature->parameters.push_tail(var);
@@ -245,7 +250,7 @@
       declarations[i] = var;
    }
 
-   ir_variable *retval = new ir_variable(type, "__retval");
+   ir_variable *retval = new(ctx) ir_variable(type, "__retval");
    signature->body.push_tail(retval);
 
    declarations[16] = retval;
@@ -257,7 +262,8 @@
  * Generate the body of a vector constructor that takes a single scalar
  */
 static void
-generate_vec_body_from_scalar(exec_list *instructions,
+generate_vec_body_from_scalar(void *ctx,
+			      exec_list *instructions,
 			      ir_variable **declarations)
 {
    ir_instruction *inst;
@@ -266,20 +272,20 @@
     * __retval.xxxx for however many vector components there are.
     */
    ir_dereference *const lhs_ref =
-      new ir_dereference_variable(declarations[16]);
-   ir_dereference *const rhs = new ir_dereference_variable(declarations[0]);
+      new(ctx) ir_dereference_variable(declarations[16]);
+   ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[0]);
 
-   ir_swizzle *lhs = new ir_swizzle(lhs_ref, 0, 0, 0, 0, 1);
+   ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, 0, 0, 0, 0, 1);
 
-   inst = new ir_assignment(lhs, rhs, NULL);
+   inst = new(ctx) ir_assignment(lhs, rhs, NULL);
    instructions->push_tail(inst);
 
-   ir_dereference *const retref = new ir_dereference_variable(declarations[16]);
+   ir_dereference *const retref = new(ctx) ir_dereference_variable(declarations[16]);
 
-   ir_swizzle *retval = new ir_swizzle(retref, 0, 0, 0, 0,
-                                       declarations[16]->type->vector_elements);
+   ir_swizzle *retval = new(ctx) ir_swizzle(retref, 0, 0, 0, 0,
+					    declarations[16]->type->vector_elements);
 
-   inst = new ir_return(retval);
+   inst = new(ctx) ir_return(retval);
    instructions->push_tail(inst);
 }
 
@@ -288,30 +294,30 @@
  * Generate the body of a vector constructor that takes multiple scalars
  */
 static void
-generate_vec_body_from_N_scalars(exec_list *instructions,
+generate_vec_body_from_N_scalars(void *ctx,
+				 exec_list *instructions,
 				 ir_variable **declarations)
 {
    ir_instruction *inst;
    const glsl_type *const vec_type = declarations[16]->type;
 
-
    /* Generate an assignment of each parameter to a single component of
     * __retval.x and return __retval.
     */
    for (unsigned i = 0; i < vec_type->vector_elements; i++) {
       ir_dereference *const lhs_ref =
-	 new ir_dereference_variable(declarations[16]);
-      ir_dereference *const rhs = new ir_dereference_variable(declarations[i]);
+	 new(ctx) ir_dereference_variable(declarations[16]);
+      ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[i]);
 
-      ir_swizzle *lhs = new ir_swizzle(lhs_ref, i, 0, 0, 0, 1);
+      ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, i, 0, 0, 0, 1);
 
-      inst = new ir_assignment(lhs, rhs, NULL);
+      inst = new(ctx) ir_assignment(lhs, rhs, NULL);
       instructions->push_tail(inst);
    }
 
-   ir_dereference *retval = new ir_dereference_variable(declarations[16]);
+   ir_dereference *retval = new(ctx) ir_dereference_variable(declarations[16]);
 
-   inst = new ir_return(retval);
+   inst = new(ctx) ir_return(retval);
    instructions->push_tail(inst);
 }
 
@@ -320,7 +326,8 @@
  * Generate the body of a matrix constructor that takes a single scalar
  */
 static void
-generate_mat_body_from_scalar(exec_list *instructions,
+generate_mat_body_from_scalar(void *ctx,
+			      exec_list *instructions,
 			      ir_variable **declarations)
 {
    ir_instruction *inst;
@@ -347,49 +354,50 @@
     */
    const glsl_type *const column_type = declarations[16]->type->column_type();
    const glsl_type *const row_type = declarations[16]->type->row_type();
-   ir_variable *const column = new ir_variable(column_type, "v");
+
+   ir_variable *const column = new(ctx) ir_variable(column_type, "v");
 
    instructions->push_tail(column);
 
-   ir_dereference *const lhs_ref = new ir_dereference_variable(column);
-   ir_dereference *const rhs = new ir_dereference_variable(declarations[0]);
+   ir_dereference *const lhs_ref = new(ctx) ir_dereference_variable(column);
+   ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[0]);
 
-   ir_swizzle *lhs = new ir_swizzle(lhs_ref, 0, 0, 0, 0, 1);
+   ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, 0, 0, 0, 0, 1);
 
-   inst = new ir_assignment(lhs, rhs, NULL);
+   inst = new(ctx) ir_assignment(lhs, rhs, NULL);
    instructions->push_tail(inst);
 
    for (unsigned i = 1; i < column_type->vector_elements; i++) {
-      ir_dereference *const lhs_ref = new ir_dereference_variable(column);
-      ir_constant *const zero = new ir_constant(0.0f);
+      ir_dereference *const lhs_ref = new(ctx) ir_dereference_variable(column);
+      ir_constant *const zero = new(ctx) ir_constant(0.0f);
 
-      ir_swizzle *lhs = new ir_swizzle(lhs_ref, i, 0, 0, 0, 1);
+      ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, i, 0, 0, 0, 1);
 
-      inst = new ir_assignment(lhs, zero, NULL);
+      inst = new(ctx) ir_assignment(lhs, zero, NULL);
       instructions->push_tail(inst);
    }
 
 
    for (unsigned i = 0; i < row_type->vector_elements; i++) {
       static const unsigned swiz[] = { 1, 1, 1, 0, 1, 1, 1 };
-      ir_dereference *const rhs_ref = new ir_dereference_variable(column);
+      ir_dereference *const rhs_ref = new(ctx) ir_dereference_variable(column);
 
       /* This will be .xyyy when i=0, .yxyy when i=1, etc.
        */
-      ir_swizzle *rhs = new ir_swizzle(rhs_ref, swiz[3 - i], swiz[4 - i],
-                                       swiz[5 - i], swiz[6 - i],
-				       column_type->vector_elements);
+      ir_swizzle *rhs = new(ctx) ir_swizzle(rhs_ref, swiz[3 - i], swiz[4 - i],
+					    swiz[5 - i], swiz[6 - i],
+					    column_type->vector_elements);
 
-      ir_constant *const idx = new ir_constant(int(i));
+      ir_constant *const idx = new(ctx) ir_constant(int(i));
       ir_dereference *const lhs =
-	 new ir_dereference_array(declarations[16], idx);
+	 new(ctx) ir_dereference_array(declarations[16], idx);
 
-      inst = new ir_assignment(lhs, rhs, NULL);
+      inst = new(ctx) ir_assignment(lhs, rhs, NULL);
       instructions->push_tail(inst);
    }
 
-   ir_dereference *const retval = new ir_dereference_variable(declarations[16]);
-   inst = new ir_return(retval);
+   ir_dereference *const retval = new(ctx) ir_dereference_variable(declarations[16]);
+   inst = new(ctx) ir_return(retval);
    instructions->push_tail(inst);
 }
 
@@ -398,38 +406,38 @@
  * Generate the body of a vector constructor that takes multiple scalars
  */
 static void
-generate_mat_body_from_N_scalars(exec_list *instructions,
+generate_mat_body_from_N_scalars(void *ctx,
+				 exec_list *instructions,
 				 ir_variable **declarations)
 {
    ir_instruction *inst;
    const glsl_type *const row_type = declarations[16]->type->row_type();
    const glsl_type *const column_type = declarations[16]->type->column_type();
 
-
    /* Generate an assignment of each parameter to a single component of
     * of a particular column of __retval and return __retval.
     */
    for (unsigned i = 0; i < column_type->vector_elements; i++) {
       for (unsigned j = 0; j < row_type->vector_elements; j++) {
-	 ir_constant *row_index = new ir_constant(int(i));
+	 ir_constant *row_index = new(ctx) ir_constant(int(i));
 	 ir_dereference *const row_access =
-	    new ir_dereference_array(declarations[16], row_index);
+	    new(ctx) ir_dereference_array(declarations[16], row_index);
 
-	 ir_swizzle *component_access = new ir_swizzle(row_access,
-	                                               j, 0, 0, 0, 1);
+	 ir_swizzle *component_access = new(ctx) ir_swizzle(row_access,
+							    j, 0, 0, 0, 1);
 
 	 const unsigned param = (i * row_type->vector_elements) + j;
 	 ir_dereference *const rhs =
-	    new ir_dereference_variable(declarations[param]);
+	    new(ctx) ir_dereference_variable(declarations[param]);
 
-	 inst = new ir_assignment(component_access, rhs, NULL);
+	 inst = new(ctx) ir_assignment(component_access, rhs, NULL);
 	 instructions->push_tail(inst);
       }
    }
 
-   ir_dereference *retval = new ir_dereference_variable(declarations[16]);
+   ir_dereference *retval = new(ctx) ir_dereference_variable(declarations[16]);
 
-   inst = new ir_return(retval);
+   inst = new(ctx) ir_return(retval);
    instructions->push_tail(inst);
 }
 
@@ -444,6 +452,7 @@
 generate_constructor(glsl_symbol_table *symtab, const struct glsl_type *types,
 		     unsigned num_types, exec_list *instructions)
 {
+   void *ctx = symtab;
    ir_variable *declarations[17];
 
    for (unsigned i = 0; i < num_types; i++) {
@@ -459,7 +468,7 @@
 
       /* Generate the function block, add it to the symbol table, and emit it.
        */
-      ir_function *const f = new ir_function(types[i].name);
+      ir_function *const f = new(ctx) ir_function(types[i].name);
 
       bool added = symtab->add_function(types[i].name, f);
       assert(added);
@@ -484,31 +493,33 @@
        * appropriate from-scalars constructor.
        */
       ir_function_signature *const sig =
-         generate_constructor_intro(&types[i], 1, declarations);
+         generate_constructor_intro(ctx, &types[i], 1, declarations);
       f->add_signature(sig);
 
       if (types[i].is_vector()) {
-	 generate_vec_body_from_scalar(&sig->body, declarations);
+	 generate_vec_body_from_scalar(ctx, &sig->body, declarations);
 
 	 ir_function_signature *const vec_sig =
-	    generate_constructor_intro(&types[i], types[i].vector_elements,
+	    generate_constructor_intro(ctx,
+				       &types[i], types[i].vector_elements,
 				       declarations);
 	 f->add_signature(vec_sig);
 
-	 generate_vec_body_from_N_scalars(&vec_sig->body, declarations);
+	 generate_vec_body_from_N_scalars(ctx, &vec_sig->body, declarations);
       } else {
 	 assert(types[i].is_matrix());
 
-	 generate_mat_body_from_scalar(&sig->body, declarations);
+	 generate_mat_body_from_scalar(ctx, &sig->body, declarations);
 
 	 ir_function_signature *const mat_sig =
-	    generate_constructor_intro(&types[i],
+	    generate_constructor_intro(ctx,
+				       &types[i],
 				       (types[i].vector_elements
 					* types[i].matrix_columns),
 				       declarations);
 	 f->add_signature(mat_sig);
 
-	 generate_mat_body_from_N_scalars(&mat_sig->body, declarations);
+	 generate_mat_body_from_N_scalars(ctx, &mat_sig->body, declarations);
       }
    }
 }
@@ -563,7 +574,7 @@
 }
 
 
-glsl_type::glsl_type(const glsl_type *array, unsigned length) :
+glsl_type::glsl_type(void *ctx, const glsl_type *array, unsigned length) :
    base_type(GLSL_TYPE_ARRAY),
    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
    sampler_type(0),
@@ -577,7 +588,7 @@
     * NUL.
     */
    const unsigned name_length = strlen(array->name) + 10 + 3;
-   char *const n = (char *) malloc(name_length);
+   char *const n = (char *) talloc_size(ctx, name_length);
 
    if (length == 0)
       snprintf(n, name_length, "%s[]", array->name);
@@ -680,9 +691,10 @@
 
 
 const glsl_type *
-glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
+glsl_type::get_array_instance(void *ctx, const glsl_type *base,
+			      unsigned array_size)
 {
-   const glsl_type key(base, array_size);
+   const glsl_type key(ctx, base, array_size);
 
    if (array_types == NULL) {
       array_types = hash_table_ctor(64, array_key_hash, array_key_compare);
@@ -690,7 +702,7 @@
 
    const glsl_type *t = (glsl_type *) hash_table_find(array_types, & key);
    if (t == NULL) {
-      t = new glsl_type(base, array_size);
+      t = new(ctx) glsl_type(ctx, base, array_size);
 
       hash_table_insert(array_types, (void *) t, t);
    }
diff --git a/glsl_types.h b/glsl_types.h
index 939c173..39e6ac9 100644
--- a/glsl_types.h
+++ b/glsl_types.h
@@ -29,6 +29,10 @@
 #include <cstring>
 #include <cassert>
 
+extern "C" {
+#include <talloc.h>
+}
+
 #define GLSL_TYPE_UINT          0
 #define GLSL_TYPE_INT           1
 #define GLSL_TYPE_FLOAT         2
@@ -61,6 +65,25 @@
 				* and \c GLSL_TYPE_UINT are valid.
 				*/
 
+   /* Callers of this talloc-based new need not call delete. It's
+    * easier to just talloc_free 'ctx' (or any of its ancestors). */
+   static void* operator new(size_t size, void *ctx)
+   {
+      void *type;
+
+      type = talloc_size(ctx, size);
+      assert(type != NULL);
+
+      return type;
+   }
+
+   /* If the user *does* call delete, that's OK, we will just
+    * talloc_free in that case. */
+   static void operator delete(void *type)
+   {
+      talloc_free(type);
+   }
+
    /**
     * \name Vector and matrix element counts
     *
@@ -198,7 +221,8 @@
    /**
     * Get the instance of an array type
     */
-   static const glsl_type *get_array_instance(const glsl_type *base,
+   static const glsl_type *get_array_instance(void *ctx,
+					      const glsl_type *base,
 					      unsigned elements);
 
    /**
@@ -387,7 +411,7 @@
    /**
     * Constructor for array types
     */
-   glsl_type(const glsl_type *array, unsigned length);
+   glsl_type(void *ctx, const glsl_type *array, unsigned length);
 
    /** Hash table containing the known array types. */
    static struct hash_table *array_types;
diff --git a/hir_field_selection.cpp b/hir_field_selection.cpp
index e60ea30..e2efff6 100644
--- a/hir_field_selection.cpp
+++ b/hir_field_selection.cpp
@@ -33,6 +33,7 @@
 				 exec_list *instructions,
 				 struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
    ir_rvalue *result = NULL;
    ir_rvalue *op;
 
@@ -62,8 +63,8 @@
 			  expr->primary_expression.identifier);
       }
    } else if (op->type->base_type == GLSL_TYPE_STRUCT) {
-      result = new ir_dereference_record(op,
-					 expr->primary_expression.identifier);
+      result = new(ctx) ir_dereference_record(op,
+					      expr->primary_expression.identifier);
 
       if (result->type->is_error()) {
 	 _mesa_glsl_error(& loc, state, "Cannot access field `%s' of "
@@ -76,5 +77,5 @@
 		       expr->primary_expression.identifier);
    }
 
-   return result ? result : ir_call::get_error_instruction();
+   return result ? result : ir_call::get_error_instruction(ctx);
 }
diff --git a/ir.cpp b/ir.cpp
index 9252ccf..2756752 100644
--- a/ir.cpp
+++ b/ir.cpp
@@ -466,8 +466,10 @@
 ir_dereference_array::ir_dereference_array(ir_variable *var,
 					   ir_rvalue *array_index)
 {
+   void *ctx = talloc_parent(var);
+
    this->array_index = array_index;
-   this->set_array(new ir_dereference_variable(var));
+   this->set_array(new(ctx) ir_dereference_variable(var));
 }
 
 
@@ -504,7 +506,9 @@
 ir_dereference_record::ir_dereference_record(ir_variable *var,
 					     const char *field)
 {
-   this->record = new ir_dereference_variable(var);
+   void *ctx = talloc_parent(var);
+
+   this->record = new(ctx) ir_dereference_variable(var);
    this->field = field;
    this->type = (this->record != NULL)
       ? this->record->type->field_type(field) : glsl_type::error_type;
@@ -615,6 +619,8 @@
 ir_swizzle *
 ir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length)
 {
+   void *ctx = talloc_parent(val);
+
    /* For each possible swizzle character, this table encodes the value in
     * \c idx_map that represents the 0th element of the vector.  For invalid
     * swizzle characters (e.g., 'k'), a special value is used that will allow
@@ -679,8 +685,8 @@
    if (str[i] != '\0')
 	 return NULL;
 
-   return new ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2],
-                         swiz_idx[3], i);
+   return new(ctx) ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2],
+			      swiz_idx[3], i);
 }
 
 #undef X
@@ -780,7 +786,6 @@
       assert(((ir_instruction *) iter.get())->as_variable() != NULL);
 
       iter.remove();
-      delete (ir_instruction*) iter.get();
    }
 
    new_params->move_nodes_to(&parameters);
@@ -795,9 +800,9 @@
 
 
 ir_call *
-ir_call::get_error_instruction()
+ir_call::get_error_instruction(void *ctx)
 {
-   ir_call *call = new ir_call;
+   ir_call *call = new(ctx) ir_call;
 
    call->type = glsl_type::error_type;
    return call;
diff --git a/ir.h b/ir.h
index 9277f76..1c95512 100644
--- a/ir.h
+++ b/ir.h
@@ -29,6 +29,10 @@
 #include <cstdio>
 #include <cstdlib>
 
+extern "C" {
+#include <talloc.h>
+}
+
 #include "list.h"
 #include "ir_visitor.h"
 #include "ir_hierarchical_visitor.h"
@@ -641,8 +645,10 @@
 
    /**
     * Get a generic ir_call object when an error occurs
+    *
+    * Any allocation will be performed with 'ctx' as talloc owner.
     */
-   static ir_call *get_error_instruction();
+   static ir_call *get_error_instruction(void *ctx);
 
    /**
     * Get an iterator for the set of acutal parameters
diff --git a/ir_clone.cpp b/ir_clone.cpp
index 6db5073..8417638 100644
--- a/ir_clone.cpp
+++ b/ir_clone.cpp
@@ -36,7 +36,8 @@
 ir_instruction *
 ir_variable::clone(struct hash_table *ht) const
 {
-   ir_variable *var = new ir_variable(type, name);
+   void *ctx = talloc_parent(this);
+   ir_variable *var = new(ctx) ir_variable(type, name);
 
    var->max_array_access = this->max_array_access;
    var->read_only = this->read_only;
@@ -55,32 +56,36 @@
 ir_instruction *
 ir_swizzle::clone(struct hash_table *ht) const
 {
-   return new ir_swizzle((ir_rvalue *)this->val->clone(ht), this->mask);
+   void *ctx = talloc_parent(this);
+   return new(ctx) ir_swizzle((ir_rvalue *)this->val->clone(ht), this->mask);
 }
 
 ir_instruction *
 ir_return::clone(struct hash_table *ht) const
 {
+   void *ctx = talloc_parent(this);
    ir_rvalue *new_value = NULL;
 
    if (this->value)
       new_value = (ir_rvalue *)this->value->clone(ht);
 
-   return new ir_return(new_value);
+   return new(ctx) ir_return(new_value);
 }
 
 ir_instruction *
 ir_loop_jump::clone(struct hash_table *ht) const
 {
+   void *ctx = talloc_parent(this);
    (void)ht;
 
-   return new ir_loop_jump(this->mode);
+   return new(ctx) ir_loop_jump(this->mode);
 }
 
 ir_instruction *
 ir_if::clone(struct hash_table *ht) const
 {
-   ir_if *new_if = new ir_if((ir_rvalue *)this->condition->clone(ht));
+   void *ctx = talloc_parent(this);
+   ir_if *new_if = new(ctx) ir_if((ir_rvalue *)this->condition->clone(ht));
 
    foreach_iter(exec_list_iterator, iter, this->then_instructions) {
       ir_instruction *ir = (ir_instruction *)iter.get();
@@ -98,7 +103,8 @@
 ir_instruction *
 ir_loop::clone(struct hash_table *ht) const
 {
-   ir_loop *new_loop = new ir_loop();
+   void *ctx = talloc_parent(this);
+   ir_loop *new_loop = new(ctx) ir_loop();
 
    if (this->from)
       new_loop->from = (ir_rvalue *)this->from->clone(ht);
@@ -119,6 +125,7 @@
 ir_instruction *
 ir_call::clone(struct hash_table *ht) const
 {
+   void *ctx = talloc_parent(this);
    exec_list new_parameters;
 
    foreach_iter(exec_list_iterator, iter, this->actual_parameters) {
@@ -126,12 +133,13 @@
       new_parameters.push_tail(ir->clone(ht));
    }
 
-   return new ir_call(this->callee, &new_parameters);
+   return new(ctx) ir_call(this->callee, &new_parameters);
 }
 
 ir_instruction *
 ir_expression::clone(struct hash_table *ht) const
 {
+   void *ctx = talloc_parent(this);
    ir_rvalue *op[2] = {NULL, NULL};
    unsigned int i;
 
@@ -139,12 +147,13 @@
       op[i] = (ir_rvalue *)this->operands[i]->clone(ht);
    }
 
-   return new ir_expression(this->operation, this->type, op[0], op[1]);
+   return new(ctx) ir_expression(this->operation, this->type, op[0], op[1]);
 }
 
 ir_instruction *
 ir_dereference_variable::clone(struct hash_table *ht) const
 {
+   void *ctx = talloc_parent(this);
    ir_variable *new_var;
 
    if (ht) {
@@ -155,27 +164,30 @@
       new_var = this->var;
    }
 
-   return new ir_dereference_variable(new_var);
+   return new(ctx) ir_dereference_variable(new_var);
 }
 
 ir_instruction *
 ir_dereference_array::clone(struct hash_table *ht) const
 {
-   return new ir_dereference_array((ir_rvalue *)this->array->clone(ht),
-				   (ir_rvalue *)this->array_index->clone(ht));
+   void *ctx = talloc_parent(this);
+   return new(ctx) ir_dereference_array((ir_rvalue *)this->array->clone(ht),
+					(ir_rvalue *)this->array_index->clone(ht));
 }
 
 ir_instruction *
 ir_dereference_record::clone(struct hash_table *ht) const
 {
-   return new ir_dereference_record((ir_rvalue *)this->record->clone(ht),
-				    this->field);
+   void *ctx = talloc_parent(this);
+   return new(ctx) ir_dereference_record((ir_rvalue *)this->record->clone(ht),
+					 this->field);
 }
 
 ir_instruction *
 ir_texture::clone(struct hash_table *ht) const
 {
-   ir_texture *new_tex = new ir_texture(this->op);
+   void *ctx = talloc_parent(this);
+   ir_texture *new_tex = new(ctx) ir_texture(this->op);
 
    new_tex->sampler = (ir_dereference *)this->sampler->clone(ht);
    new_tex->coordinate = (ir_rvalue *)this->coordinate->clone(ht);
@@ -218,9 +230,10 @@
    if (this->condition)
       new_condition = (ir_rvalue *)this->condition->clone(ht);
 
-   return new ir_assignment((ir_rvalue *)this->lhs->clone(ht),
-			    (ir_rvalue *)this->rhs->clone(ht),
-			    new_condition);
+   void *ctx = talloc_parent(this);
+   return new(ctx) ir_assignment((ir_rvalue *)this->lhs->clone(ht),
+				 (ir_rvalue *)this->rhs->clone(ht),
+				 new_condition);
 }
 
 ir_instruction *
@@ -242,6 +255,7 @@
 ir_instruction *
 ir_constant::clone(struct hash_table *ht) const
 {
+   void *ctx = talloc_parent(this);
    (void)ht;
 
    switch (this->type->base_type) {
@@ -249,10 +263,10 @@
    case GLSL_TYPE_INT:
    case GLSL_TYPE_FLOAT:
    case GLSL_TYPE_BOOL:
-      return new ir_constant(this->type, &this->value);
+      return new(ctx) ir_constant(this->type, &this->value);
 
    case GLSL_TYPE_STRUCT: {
-      ir_constant *c = new ir_constant;
+      ir_constant *c = new(ctx) ir_constant;
 
       c->type = this->type;
       for (exec_node *node = this->components.head
diff --git a/ir_constant_expression.cpp b/ir_constant_expression.cpp
index effb888..4010e46 100644
--- a/ir_constant_expression.cpp
+++ b/ir_constant_expression.cpp
@@ -127,6 +127,7 @@
 void
 ir_constant_visitor::visit(ir_expression *ir)
 {
+   void *ctx = talloc_parent(ir);
    value = NULL;
    ir_constant *op[2];
    unsigned int operand, c;
@@ -497,7 +498,7 @@
       return;
    }
 
-   this->value = new ir_constant(ir->type, &data);
+   this->value = new(ctx) ir_constant(ir->type, &data);
 }
 
 
@@ -513,6 +514,7 @@
 void
 ir_constant_visitor::visit(ir_swizzle *ir)
 {
+   void *ctx = talloc_parent(ir);
    ir_constant *v = ir->val->constant_expression_value();
 
    this->value = NULL;
@@ -534,7 +536,7 @@
 	 }
       }
 
-      this->value = new ir_constant(ir->type, &data);
+      this->value = new(ctx) ir_constant(ir->type, &data);
    }
 }
 
@@ -553,6 +555,7 @@
 void
 ir_constant_visitor::visit(ir_dereference_array *ir)
 {
+   void *ctx = talloc_parent(ir);
    ir_constant *array = ir->array->constant_expression_value();
    ir_constant *idx = ir->array_index->constant_expression_value();
 
@@ -592,11 +595,11 @@
 	    break;
 	 }
 
-	 this->value = new ir_constant(column_type, &data);
+	 this->value = new(ctx) ir_constant(column_type, &data);
       } else if (array->type->is_vector()) {
 	 const unsigned component = idx->value.u[0];
 
-	 this->value = new ir_constant(array, component);
+	 this->value = new(ctx) ir_constant(array, component);
       } else {
 	 /* FINISHME: Handle access of constant arrays. */
       }
diff --git a/ir_copy_propagation.cpp b/ir_copy_propagation.cpp
index 16a2ba7..46ef667 100644
--- a/ir_copy_propagation.cpp
+++ b/ir_copy_propagation.cpp
@@ -197,6 +197,7 @@
 static void
 add_copy(ir_assignment *ir, exec_list *acp)
 {
+   void *ctx = talloc_parent(ir);
    acp_entry *entry;
 
    if (ir->condition) {
@@ -209,7 +210,7 @@
    ir_variable *rhs_var = ir->rhs->whole_variable_referenced();
 
    if ((lhs_var != NULL) && (rhs_var != NULL)) {
-      entry = new acp_entry(lhs_var, rhs_var);
+      entry = new(ctx) acp_entry(lhs_var, rhs_var);
       acp->push_tail(entry);
    }
 }
diff --git a/ir_dead_code.cpp b/ir_dead_code.cpp
index 8465d86..01b7d2d 100644
--- a/ir_dead_code.cpp
+++ b/ir_dead_code.cpp
@@ -77,6 +77,7 @@
 variable_entry *
 ir_dead_code_visitor::get_variable_entry(ir_variable *var)
 {
+   void *ctx = talloc_parent(var);
    assert(var);
    foreach_iter(exec_list_iterator, iter, this->variable_list) {
       variable_entry *entry = (variable_entry *)iter.get();
@@ -84,7 +85,7 @@
 	 return entry;
    }
 
-   variable_entry *entry = new variable_entry(var);
+   variable_entry *entry = new(ctx) variable_entry(var);
    this->variable_list.push_tail(entry);
    return entry;
 }
diff --git a/ir_dead_code_local.cpp b/ir_dead_code_local.cpp
index d3b3858..e018770 100644
--- a/ir_dead_code_local.cpp
+++ b/ir_dead_code_local.cpp
@@ -113,6 +113,7 @@
 static bool
 process_assignment(ir_assignment *ir, exec_list *assignments)
 {
+   void *ctx = talloc_parent(ir);
    ir_variable *var = NULL;
    bool progress = false;
    kill_for_derefs_visitor v(assignments);
@@ -157,7 +158,7 @@
    }
 
    /* Add this instruction to the assignment list. */
-   assignment_entry *entry = new assignment_entry(var, ir);
+   assignment_entry *entry = new(ctx) assignment_entry(var, ir);
    assignments->push_tail(entry);
 
    if (debug) {
diff --git a/ir_expression_flattening.cpp b/ir_expression_flattening.cpp
index 3089f17..5ba24e3 100644
--- a/ir_expression_flattening.cpp
+++ b/ir_expression_flattening.cpp
@@ -80,18 +80,19 @@
 static ir_rvalue *
 operand_to_temp(ir_instruction *base_ir, ir_rvalue *ir)
 {
+   void *ctx = talloc_parent(base_ir);
    ir_variable *var;
    ir_assignment *assign;
 
-   var = new ir_variable(ir->type, "flattening_tmp");
+   var = new(ctx) ir_variable(ir->type, "flattening_tmp");
    base_ir->insert_before(var);
 
-   assign = new ir_assignment(new ir_dereference_variable(var),
-			      ir,
-			      NULL);
+   assign = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
+				   ir,
+				   NULL);
    base_ir->insert_before(assign);
 
-   return new ir_dereference_variable(var);
+   return new(ctx) ir_dereference_variable(var);
 }
 
 ir_visitor_status
diff --git a/ir_function_inlining.cpp b/ir_function_inlining.cpp
index 851c0dd..e55780c 100644
--- a/ir_function_inlining.cpp
+++ b/ir_function_inlining.cpp
@@ -94,13 +94,14 @@
 static void
 replace_return_with_assignment(ir_instruction *ir, void *data)
 {
+   void *ctx = talloc_parent(ir);
    ir_variable *retval = (ir_variable *)data;
    ir_return *ret = ir->as_return();
 
    if (ret) {
       if (ret->value) {
-	 ir_rvalue *lhs = new ir_dereference_variable(retval);
-	 ret->insert_before(new ir_assignment(lhs, ret->value, NULL));
+	 ir_rvalue *lhs = new(ctx) ir_dereference_variable(retval);
+	 ret->insert_before(new(ctx) ir_assignment(lhs, ret->value, NULL));
 	 ret->remove();
       } else {
 	 /* un-valued return has to be the last return, or we shouldn't
@@ -114,6 +115,7 @@
 ir_rvalue *
 ir_call::generate_inline(ir_instruction *next_ir)
 {
+   void *ctx = talloc_parent(this);
    ir_variable **parameters;
    int num_parameters;
    int i;
@@ -130,7 +132,7 @@
 
    /* Generate storage for the return value. */
    if (this->callee->return_type) {
-      retval = new ir_variable(this->callee->return_type, "__retval");
+      retval = new(ctx) ir_variable(this->callee->return_type, "__retval");
       next_ir->insert_before(retval);
    }
 
@@ -154,8 +156,8 @@
 	  sig_param->mode == ir_var_inout) {
 	 ir_assignment *assign;
 
-	 assign = new ir_assignment(new ir_dereference_variable(parameters[i]),
-				    param, NULL);
+	 assign = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(parameters[i]),
+					 param, NULL);
 	 next_ir->insert_before(assign);
       }
 
@@ -185,9 +187,9 @@
 	  parameters[i]->mode == ir_var_inout) {
 	 ir_assignment *assign;
 
-	 assign = new ir_assignment(param->as_rvalue(),
-				    new ir_dereference_variable(parameters[i]),
-				    NULL);
+	 assign = new(ctx) ir_assignment(param->as_rvalue(),
+					 new(ctx) ir_dereference_variable(parameters[i]),
+					 NULL);
 	 next_ir->insert_before(assign);
       }
 
@@ -199,7 +201,7 @@
    hash_table_dtor(ht);
 
    if (retval)
-      return new ir_dereference_variable(retval);
+      return new(ctx) ir_dereference_variable(retval);
    else
       return NULL;
 }
diff --git a/ir_reader.cpp b/ir_reader.cpp
index ee320dd..7383c42 100644
--- a/ir_reader.cpp
+++ b/ir_reader.cpp
@@ -70,7 +70,8 @@
 _mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions,
 		   const char *src)
 {
-   s_expression *expr = s_expression::read_expression(src);
+   void *ctx = talloc_parent(state);
+   s_expression *expr = s_expression::read_expression(ctx, src);
    if (expr == NULL) {
       ir_read_error(state, NULL, "couldn't parse S-Expression.");
       return;
@@ -137,7 +138,7 @@
 	    return NULL;
 	 }
 
-	 return glsl_type::get_array_instance(base_type, size->value());
+	 return glsl_type::get_array_instance(st, base_type, size->value());
       } else if (strcmp(type_sym->value(), "struct") == 0) {
 	 assert(false); // FINISHME
       } else {
@@ -190,6 +191,7 @@
 static ir_function *
 read_function(_mesa_glsl_parse_state *st, s_list *list, bool skip_body)
 {
+   void *ctx = talloc_parent(st);
    if (list->length() < 3) {
       ir_read_error(st, list, "Expected (function <name> (signature ...) ...)");
       return NULL;
@@ -203,7 +205,7 @@
 
    ir_function *f = st->symbols->get_function(name->value());
    if (f == NULL) {
-      f = new ir_function(name->value());
+      f = new(ctx) ir_function(name->value());
       bool added = st->symbols->add_function(name->value(), f);
       assert(added);
    }
@@ -233,6 +235,7 @@
 read_function_sig(_mesa_glsl_parse_state *st, ir_function *f, s_list *list,
 		  bool skip_body)
 {
+   void *ctx = talloc_parent(st);
    if (list->length() != 4) {
       ir_read_error(st, list, "Expected (signature <type> (parameters ...) "
 			      "(<instruction> ...))");
@@ -286,7 +289,7 @@
 	 return;
       }
    } else {
-      sig = new ir_function_signature(return_type);
+      sig = new(ctx) ir_function_signature(return_type);
       f->add_signature(sig);
    }
 
@@ -331,12 +334,13 @@
 read_instruction(_mesa_glsl_parse_state *st, s_expression *expr,
 	         ir_loop *loop_ctx)
 {
+   void *ctx = talloc_parent(st);
    s_symbol *symbol = SX_AS_SYMBOL(expr);
    if (symbol != NULL) {
       if (strcmp(symbol->value(), "break") == 0 && loop_ctx != NULL)
-	 return new ir_loop_jump(ir_loop_jump::jump_break);
+	 return new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
       if (strcmp(symbol->value(), "continue") == 0 && loop_ctx != NULL)
-	 return new ir_loop_jump(ir_loop_jump::jump_continue);
+	 return new(ctx) ir_loop_jump(ir_loop_jump::jump_continue);
    }
 
    s_list *list = SX_AS_LIST(expr);
@@ -372,6 +376,7 @@
 static ir_variable *
 read_declaration(_mesa_glsl_parse_state *st, s_list *list)
 {
+   void *ctx = talloc_parent(st);
    if (list->length() != 4) {
       ir_read_error(st, list, "expected (declare (<qualifiers>) <type> "
 			      "<name>)");
@@ -395,7 +400,7 @@
       return NULL;
    }
 
-   ir_variable *var = new ir_variable(type, var_name->value());
+   ir_variable *var = new(ctx) ir_variable(type, var_name->value());
 
    foreach_iter(exec_list_iterator, it, quals->subexpressions) {
       s_symbol *qualifier = SX_AS_SYMBOL(it.get());
@@ -443,6 +448,7 @@
 static ir_if *
 read_if(_mesa_glsl_parse_state *st, s_list *list, ir_loop *loop_ctx)
 {
+   void *ctx = talloc_parent(st);
    if (list->length() != 4) {
       ir_read_error(st, list, "expected (if <condition> (<then> ...) "
                           "(<else> ...))");
@@ -459,7 +465,7 @@
    s_expression *then_expr = (s_expression*) cond_expr->next;
    s_expression *else_expr = (s_expression*) then_expr->next;
 
-   ir_if *iff = new ir_if(condition);
+   ir_if *iff = new(ctx) ir_if(condition);
 
    read_instructions(st, &iff->then_instructions, then_expr, loop_ctx);
    read_instructions(st, &iff->else_instructions, else_expr, loop_ctx);
@@ -474,6 +480,7 @@
 static ir_loop *
 read_loop(_mesa_glsl_parse_state *st, s_list *list)
 {
+   void *ctx = talloc_parent(st);
    if (list->length() != 6) {
       ir_read_error(st, list, "expected (loop <counter> <from> <to> "
 			      "<increment> <body>)");
@@ -488,7 +495,7 @@
 
    // FINISHME: actually read the count/from/to fields.
 
-   ir_loop *loop = new ir_loop;
+   ir_loop *loop = new(ctx) ir_loop;
    read_instructions(st, &loop->body_instructions, body_expr, loop);
    if (st->error) {
       delete loop;
@@ -501,6 +508,7 @@
 static ir_return *
 read_return(_mesa_glsl_parse_state *st, s_list *list)
 {
+   void *ctx = talloc_parent(st);
    if (list->length() != 2) {
       ir_read_error(st, list, "expected (return <rvalue>)");
       return NULL;
@@ -514,7 +522,7 @@
       return NULL;
    }
 
-   return new ir_return(retval);
+   return new(ctx) ir_return(retval);
 }
 
 
@@ -556,6 +564,7 @@
 static ir_assignment *
 read_assignment(_mesa_glsl_parse_state *st, s_list *list)
 {
+   void *ctx = talloc_parent(st);
    if (list->length() != 4) {
       ir_read_error(st, list, "expected (assign <condition> <lhs> <rhs>)");
       return NULL;
@@ -584,12 +593,13 @@
       return NULL;
    }
 
-   return new ir_assignment(lhs, rhs, condition);
+   return new(ctx) ir_assignment(lhs, rhs, condition);
 }
 
 static ir_call *
 read_call(_mesa_glsl_parse_state *st, s_list *list)
 {
+   void *ctx = talloc_parent(st);
    if (list->length() != 3) {
       ir_read_error(st, list, "expected (call <name> (<param> ...))");
       return NULL;
@@ -628,12 +638,13 @@
       return NULL;
    }
 
-   return new ir_call(callee, &parameters);
+   return new(ctx) ir_call(callee, &parameters);
 }
 
 static ir_expression *
 read_expression(_mesa_glsl_parse_state *st, s_list *list)
 {
+   void *ctx = talloc_parent(st);
    const unsigned list_length = list->length();
    if (list_length < 4) {
       ir_read_error(st, list, "expected (expression <type> <operator> "
@@ -693,7 +704,7 @@
       }
    }
 
-   return new ir_expression(op, type, arg1, arg2);
+   return new(ctx) ir_expression(op, type, arg1, arg2);
 }
 
 static ir_swizzle *
@@ -738,6 +749,7 @@
 static ir_constant *
 read_constant(_mesa_glsl_parse_state *st, s_list *list)
 {
+   void *ctx = talloc_parent(st);
    if (list->length() != 3) {
       ir_read_error(st, list, "expected (constant <type> (<num> ... <num>))");
       return NULL;
@@ -803,7 +815,7 @@
       ++k;
    }
 
-   return new ir_constant(type, &data);
+   return new(ctx) ir_constant(type, &data);
 }
 
 static ir_dereference *
@@ -828,6 +840,7 @@
 static ir_dereference *
 read_var_ref(_mesa_glsl_parse_state *st, s_list *list)
 {
+   void *ctx = talloc_parent(st);
    if (list->length() != 2) {
       ir_read_error(st, list, "expected (var_ref <variable name>)");
       return NULL;
@@ -844,12 +857,13 @@
       return NULL;
    }
 
-   return new ir_dereference_variable(var);
+   return new(ctx) ir_dereference_variable(var);
 }
 
 static ir_dereference *
 read_array_ref(_mesa_glsl_parse_state *st, s_list *list)
 {
+   void *ctx = talloc_parent(st);
    if (list->length() != 3) {
       ir_read_error(st, list, "expected (array_ref <rvalue> <index>)");
       return NULL;
@@ -864,12 +878,13 @@
 
    s_expression *idx_expr = (s_expression*) subj_expr->next;
    ir_rvalue *idx = read_rvalue(st, idx_expr);
-   return new ir_dereference_array(subject, idx);
+   return new(ctx) ir_dereference_array(subject, idx);
 }
 
 static ir_dereference *
 read_record_ref(_mesa_glsl_parse_state *st, s_list *list)
 {
+   void *ctx = talloc_parent(st);
    if (list->length() != 3) {
       ir_read_error(st, list, "expected (record_ref <rvalue> <field>)");
       return NULL;
@@ -887,7 +902,7 @@
       ir_read_error(st, list, "expected (record_ref ... <field name>)");
       return NULL;
    }
-   return new ir_dereference_record(subject, field->value());
+   return new(ctx) ir_dereference_record(subject, field->value());
 }
 
 static bool
@@ -905,6 +920,7 @@
 static ir_texture *
 read_texture(_mesa_glsl_parse_state *st, s_list *list)
 {
+   void *ctx = talloc_parent(st);
    s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.head);
    assert(tag != NULL);
 
@@ -917,7 +933,7 @@
       return NULL;
    }
 
-   ir_texture *tex = new ir_texture(op);
+   ir_texture *tex = new(ctx) ir_texture(op);
 
    // Read sampler (must be a deref)
    s_expression *sampler_expr = (s_expression *) tag->next;
diff --git a/ir_variable.cpp b/ir_variable.cpp
index efebe91..15a4a92 100644
--- a/ir_variable.cpp
+++ b/ir_variable.cpp
@@ -35,7 +35,7 @@
 	     const glsl_type *type, exec_list *instructions,
 		     glsl_symbol_table *symtab)
 {
-   ir_variable *var = new ir_variable(type, name);
+   ir_variable *var = new(symtab) ir_variable(type, name);
 
    var->mode = mode;
    switch (var->mode) {
@@ -104,7 +104,7 @@
     * FINISHME: for now.
     */
    const glsl_type *const mat4_array_type =
-      glsl_type::get_array_instance(glsl_type::mat4_type, 4);
+      glsl_type::get_array_instance(symtab, glsl_type::mat4_type, 4);
 
    add_variable("gl_TextureMatrix", ir_var_uniform, -1, mat4_array_type,
 		instructions, symtab);
@@ -122,7 +122,8 @@
     * FINISHME: at least 8, so hard-code 8 for now.
     */
    const glsl_type *const light_source_array_type =
-      glsl_type::get_array_instance(symtab->get_type("gl_LightSourceParameters"), 8);
+      glsl_type::get_array_instance(symtab,
+				    symtab->get_type("gl_LightSourceParameters"), 8);
 
    add_variable("gl_LightSource", ir_var_uniform, -1, light_source_array_type,
 		instructions, symtab);
@@ -157,7 +158,7 @@
     * FINISHME: for now.
     */
    const glsl_type *const vec4_array_type =
-      glsl_type::get_array_instance(glsl_type::vec4_type, 4);
+      glsl_type::get_array_instance(symtab, glsl_type::vec4_type, 4);
 
    add_variable("gl_TexCoord", ir_var_out, VERT_RESULT_TEX0, vec4_array_type,
 		instructions, symtab);
@@ -179,6 +180,7 @@
 generate_130_vs_variables(exec_list *instructions,
 			  glsl_symbol_table *symtab)
 {
+   void *ctx = symtab;
    generate_120_vs_variables(instructions, symtab);
 
    for (unsigned i = 0; i < Elements(builtin_130_vs_variables); i++) {
@@ -190,7 +192,7 @@
     * FINISHME: the value of GL_MAX_CLIP_DISTANCES.
     */
    const glsl_type *const clip_distance_array_type =
-      glsl_type::get_array_instance(glsl_type::float_type, 8);
+      glsl_type::get_array_instance(ctx, glsl_type::float_type, 8);
 
    /* FINISHME: gl_ClipDistance needs a real location assigned. */
    add_variable("gl_ClipDistance", ir_var_out, -1, clip_distance_array_type,
@@ -240,7 +242,7 @@
     * FINISHME: for now.
     */
    const glsl_type *const vec4_array_type =
-      glsl_type::get_array_instance(glsl_type::vec4_type, 4);
+      glsl_type::get_array_instance(symtab, glsl_type::vec4_type, 4);
 
    add_variable("gl_TexCoord", ir_var_in, FRAG_ATTRIB_TEX0, vec4_array_type,
 		instructions, symtab);
@@ -256,7 +258,7 @@
     * FINISHME: at least 1, so hard-code 1 for now.
     */
    const glsl_type *const vec4_array_type =
-      glsl_type::get_array_instance(glsl_type::vec4_type, 1);
+      glsl_type::get_array_instance(symtab, glsl_type::vec4_type, 1);
 
    ir_variable *const fd =
       add_variable("gl_FragData", ir_var_out, FRAG_RESULT_DATA0,
@@ -279,13 +281,14 @@
 generate_130_fs_variables(exec_list *instructions,
 			  glsl_symbol_table *symtab)
 {
+   void *ctx = symtab;
    generate_120_fs_variables(instructions, symtab);
 
    /* FINISHME: The size of this array is implementation dependent based on
     * FINISHME: the value of GL_MAX_CLIP_DISTANCES.
     */
    const glsl_type *const clip_distance_array_type =
-      glsl_type::get_array_instance(glsl_type::float_type, 8);
+      glsl_type::get_array_instance(ctx, glsl_type::float_type, 8);
 
    /* FINISHME: gl_ClipDistance needs a real location assigned. */
    add_variable("gl_ClipDistance", ir_var_in, -1, clip_distance_array_type,
diff --git a/ir_vec_index_to_swizzle.cpp b/ir_vec_index_to_swizzle.cpp
index eb0e556..bbd8737 100644
--- a/ir_vec_index_to_swizzle.cpp
+++ b/ir_vec_index_to_swizzle.cpp
@@ -60,6 +60,7 @@
 ir_rvalue *
 ir_vec_index_to_swizzle_visitor::convert_vec_index_to_swizzle(ir_rvalue *ir)
 {
+   void *ctx = talloc_parent(ir);
    ir_dereference_array *deref = ir->as_dereference_array();
    ir_constant *ir_constant;
 
@@ -75,7 +76,8 @@
       return ir;
 
    this->progress = true;
-   return new ir_swizzle(deref->array, ir_constant->value.i[0], 0, 0, 0, 1);
+   return new(ctx) ir_swizzle(deref->array,
+			      ir_constant->value.i[0], 0, 0, 0, 1);
 }
 
 ir_visitor_status
diff --git a/list.h b/list.h
index 0b91647..7732d66 100644
--- a/list.h
+++ b/list.h
@@ -66,7 +66,13 @@
 
 #ifndef __cplusplus
 #include <stddef.h>
+#include <talloc.h>
+#else
+extern "C" {
+#include <talloc.h>
+}
 #endif
+
 #include <assert.h>
 
 struct exec_node {
@@ -74,6 +80,25 @@
    struct exec_node *prev;
 
 #ifdef __cplusplus
+   /* Callers of this talloc-based new need not call delete. It's
+    * easier to just talloc_free 'ctx' (or any of its ancestors). */
+   static void* operator new(size_t size, void *ctx)
+   {
+      void *node;
+
+      node = talloc_size(ctx, size);
+      assert(node != NULL);
+
+      return node;
+   }
+
+   /* If the user *does* call delete, that's OK, we will just
+    * talloc_free in that case. */
+   static void operator delete(void *node)
+   {
+      talloc_free(node);
+   }
+
    exec_node() : next(NULL), prev(NULL)
    {
       /* empty */
diff --git a/main.cpp b/main.cpp
index 17f25d7..dcd9bd6 100644
--- a/main.cpp
+++ b/main.cpp
@@ -29,10 +29,6 @@
 #include <fcntl.h>
 #include <unistd.h>
 
-extern "C" {
-#include <talloc.h>
-}
-
 #include "ast.h"
 #include "glsl_parser_extras.h"
 #include "glsl_parser.h"
@@ -40,9 +36,9 @@
 #include "ir_print_visitor.h"
 #include "program.h"
 
-
+/* Returned string will have 'ctx' as its talloc owner. */
 static char *
-load_text_file(const char *file_name, size_t *size)
+load_text_file(void *ctx, const char *file_name, size_t *size)
 {
 	char *text = NULL;
 	struct stat st;
@@ -55,7 +51,7 @@
 	}
 
 	if (fstat(fd, & st) == 0) {
-	   text = (char *) malloc(st.st_size + 1);
+	   text = (char *) talloc_size(ctx, st.st_size + 1);
 		if (text != NULL) {
 			do {
 				ssize_t bytes = read(fd, text + total_read,
@@ -106,38 +102,39 @@
 void
 compile_shader(struct glsl_shader *shader)
 {
-   struct _mesa_glsl_parse_state state;
+   struct _mesa_glsl_parse_state *state;
 
-   memset(& state, 0, sizeof(state));
+   state = talloc_zero(talloc_parent(shader), struct _mesa_glsl_parse_state);
+
    switch (shader->Type) {
-   case GL_VERTEX_SHADER:   state.target = vertex_shader; break;
-   case GL_FRAGMENT_SHADER: state.target = fragment_shader; break;
-   case GL_GEOMETRY_SHADER: state.target = geometry_shader; break;
+   case GL_VERTEX_SHADER:   state->target = vertex_shader; break;
+   case GL_FRAGMENT_SHADER: state->target = fragment_shader; break;
+   case GL_GEOMETRY_SHADER: state->target = geometry_shader; break;
    }
 
-   state.scanner = NULL;
-   state.translation_unit.make_empty();
-   state.symbols = new glsl_symbol_table;
-   state.info_log = talloc_strdup(shader, "");
-   state.error = false;
-   state.temp_index = 0;
-   state.loop_or_switch_nesting = NULL;
-   state.ARB_texture_rectangle_enable = true;
+   state->scanner = NULL;
+   state->translation_unit.make_empty();
+   state->symbols = new(shader) glsl_symbol_table;
+   state->info_log = talloc_strdup(shader, "");
+   state->error = false;
+   state->temp_index = 0;
+   state->loop_or_switch_nesting = NULL;
+   state->ARB_texture_rectangle_enable = true;
 
    /* Create a new context for the preprocessor output.  Ultimately, this
     * should probably be the parser context, but there isn't one yet.
    */
    const char *source = shader->Source;
-   state.error = preprocess(shader, &source, &state.info_log);
+   state->error = preprocess(shader, &source, &state->info_log);
 
-   if (!state.error) {
-      _mesa_glsl_lexer_ctor(& state, source);
-      _mesa_glsl_parse(& state);
-      _mesa_glsl_lexer_dtor(& state);
+   if (!state->error) {
+      _mesa_glsl_lexer_ctor(state, source);
+      _mesa_glsl_parse(state);
+      _mesa_glsl_lexer_dtor(state);
    }
 
    if (dump_ast) {
-      foreach_list_const(n, &state.translation_unit) {
+      foreach_list_const(n, &state->translation_unit) {
 	 ast_node *ast = exec_node_data(ast_node, n, link);
 	 ast->print();
       }
@@ -145,13 +142,13 @@
    }
 
    shader->ir.make_empty();
-   if (!state.error && !state.translation_unit.is_empty())
-      _mesa_ast_to_hir(&shader->ir, &state);
+   if (!state->error && !state->translation_unit.is_empty())
+      _mesa_ast_to_hir(&shader->ir, state);
 
    validate_ir_tree(&shader->ir);
 
    /* Optimization passes */
-   if (!state.error && !shader->ir.is_empty()) {
+   if (!state->error && !shader->ir.is_empty()) {
       bool progress;
       do {
 	 progress = false;
@@ -171,17 +168,19 @@
    validate_ir_tree(&shader->ir);
 
    /* Print out the resulting IR */
-   if (!state.error && dump_lir) {
-      _mesa_print_ir(&shader->ir, &state);
+   if (!state->error && dump_lir) {
+      _mesa_print_ir(&shader->ir, state);
    }
 
-   shader->symbols = state.symbols;
-   shader->CompileStatus = !state.error;
+   shader->symbols = state->symbols;
+   shader->CompileStatus = !state->error;
 
    if (shader->InfoLog)
       talloc_free(shader->InfoLog);
 
-   shader->InfoLog = state.info_log;
+   shader->InfoLog = state->info_log;
+
+   talloc_free(state);
 
    return;
 }
@@ -200,20 +199,21 @@
    if (argc <= optind)
       usage_fail(argv[0]);
 
-   struct glsl_program whole_program;
-   memset(&whole_program, 0, sizeof(whole_program));
+   struct glsl_program *whole_program;
+
+   whole_program = talloc_zero (NULL, struct glsl_program);
+   assert(whole_program != NULL);
 
    for (/* empty */; argc > optind; optind++) {
-      whole_program.Shaders = (struct glsl_shader **)
-	 realloc(whole_program.Shaders,
-		 sizeof(struct glsl_shader *) * (whole_program.NumShaders + 1));
-      assert(whole_program.Shaders != NULL);
+      whole_program->Shaders = (struct glsl_shader **)
+	 talloc_realloc(whole_program, whole_program->Shaders,
+			struct glsl_shader *, whole_program->NumShaders + 1);
+      assert(whole_program->Shaders != NULL);
 
-      /* talloc context should probably be whole_program */
-      struct glsl_shader *shader = talloc_zero(NULL, glsl_shader);
+      struct glsl_shader *shader = talloc_zero(whole_program, glsl_shader);
 
-      whole_program.Shaders[whole_program.NumShaders] = shader;
-      whole_program.NumShaders++;
+      whole_program->Shaders[whole_program->NumShaders] = shader;
+      whole_program->NumShaders++;
 
       const unsigned len = strlen(argv[optind]);
       if (len < 6)
@@ -229,7 +229,8 @@
       else
 	 usage_fail(argv[0]);
 
-      shader->Source = load_text_file(argv[optind], &shader->SourceLen);
+      shader->Source = load_text_file(whole_program,
+				      argv[optind], &shader->SourceLen);
       if (shader->Source == NULL) {
 	 printf("File \"%s\" does not exist.\n", argv[optind]);
 	 exit(EXIT_FAILURE);
@@ -245,9 +246,11 @@
    }
 
    if ((status == EXIT_SUCCESS) && do_link)  {
-      link_shaders(&whole_program);
-      status = (whole_program.LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE;
+      link_shaders(whole_program);
+      status = (whole_program->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE;
    }
 
+   talloc_free(whole_program);
+
    return status;
 }
diff --git a/s_expression.cpp b/s_expression.cpp
index 4022dfa..26be23e 100644
--- a/s_expression.cpp
+++ b/s_expression.cpp
@@ -30,29 +30,14 @@
 
 s_symbol::s_symbol(const char *tmp)
 {
-   this->str = new char [strlen(tmp) + 1];
-   strcpy(this->str, tmp);
-}
-
-s_symbol::~s_symbol()
-{
-   delete [] this->str;
-   this->str = NULL;
+   this->str = talloc_strdup (this, tmp);
+   assert(this->str != NULL);
 }
 
 s_list::s_list()
 {
 }
 
-s_list::~s_list()
-{
-   exec_list_iterator it(this->subexpressions.iterator());
-   while (it.has_next())
-      it.remove();
-
-   assert(this->subexpressions.is_empty());
-}
-
 unsigned
 s_list::length() const
 {
@@ -64,7 +49,7 @@
 }
 
 static s_expression *
-read_atom(const char *& src)
+read_atom(void *ctx, const char *& src)
 {
    char buf[101];
    int n;
@@ -80,20 +65,20 @@
       int i = strtol(buf, &int_end, 10);
       // If strtod matched more characters, it must have a decimal part
       if (float_end > int_end)
-	 return new s_float(f);
+	 return new(ctx) s_float(f);
 
-      return new s_int(i);
+      return new(ctx) s_int(i);
    }
    // Not a number; return a symbol.
-   return new s_symbol(buf);
+   return new(ctx) s_symbol(buf);
 }
 
 s_expression *
-s_expression::read_expression(const char *&src)
+s_expression::read_expression(void *ctx, const char *&src)
 {
    assert(src != NULL);
 
-   s_expression *atom = read_atom(src);
+   s_expression *atom = read_atom(ctx, src);
    if (atom != NULL)
       return atom;
 
@@ -102,10 +87,10 @@
    if (sscanf(src, " %c%n", &c, &n) == 1 && c == '(') {
       src += n;
 
-      s_list *list = new s_list;
+      s_list *list = new(ctx) s_list;
       s_expression *expr;
 
-      while ((expr = read_expression(src)) != NULL) {
+      while ((expr = read_expression(ctx, src)) != NULL) {
 	 list->subexpressions.push_tail(expr);
       }
       if (sscanf(src, " %c%n", &c, &n) != 1 || c != ')') {
diff --git a/s_expression.h b/s_expression.h
index d5e52c1..1a0c03c 100644
--- a/s_expression.h
+++ b/s_expression.h
@@ -46,13 +46,13 @@
 class s_expression : public exec_node
 {
 public:
-   virtual ~s_expression() { }
-
    /**
     * Read an S-Expression from the given string.
     * Advances the supplied pointer to just after the expression read.
+    *
+    * Any allocation will be performed with 'ctx' as the talloc owner.
     */
-   static s_expression *read_expression(const char *&src);
+   static s_expression *read_expression(void *ctx, const char *&src);
 
    /**
     * Print out an S-Expression.  Useful for debugging.
@@ -73,8 +73,6 @@
 class s_number : public s_expression
 {
 public:
-   virtual ~s_number() { }
-
    bool is_number() const { return true; }
 
    virtual float fvalue() = 0;
@@ -87,7 +85,6 @@
 {
 public:
    s_int(int x) : val(x) { }
-   virtual ~s_int() { }
 
    bool is_int() const { return true; }
 
@@ -104,7 +101,6 @@
 {
 public:
    s_float(float x) : val(x) { }
-   virtual ~s_float() { }
 
    float fvalue() { return this->val; }
 
@@ -118,7 +114,6 @@
 {
 public:
    s_symbol(const char *);
-   virtual ~s_symbol();
 
    bool is_symbol() const { return true; }
 
@@ -135,7 +130,6 @@
 {
 public:
    s_list();
-   virtual ~s_list();
 
    virtual bool is_list() const { return true; }
    unsigned length() const;