ast_node: Add new talloc-based new()
authorCarl Worth <cworth@cworth.org>
Thu, 24 Jun 2010 00:12:11 +0000 (17:12 -0700)
committerCarl Worth <cworth@cworth.org>
Thu, 24 Jun 2010 01:15:28 +0000 (18:15 -0700)
And use the talloc-based new for all of the ast objects created by the
parser.  This closes a lot of memory leaks, and will allow us to use
these ast objects as talloc parents in the future, (for things like
exec_nodes, etc.).

This closes 164 leaks in the glsl-orangebook-ch06-bump.frag test:

total heap usage: 55,623 allocs, 14,553 frees
(was 14,389 frees)

ast.h
glsl_parser.ypp

diff --git a/ast.h b/ast.h
index 782e2c7ce740ad1c389150a149b449087a1f5e39..de300e719c436f8b95d0324f4b176baa9b39450f 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -36,6 +36,25 @@ struct YYLTYPE;
 
 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);
index ae009ed20cb5521b810c683ca99d7c946bae5c39..4132495f403fbedfedf4af47848ade8e043f272d 100644 (file)
@@ -255,31 +255,36 @@ variable_identifier:
 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 @@ postfix_expression:
        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:
        }
        | 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_or_method:
        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_call_header:
 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 @@ unary_expression:
        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 @@ multiplicative_expression:
        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 @@ additive_expression:
        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 @@ shift_expression:
        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 @@ relational_expression:
        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 @@ equality_expression:
        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 @@ and_expression:
        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 @@ exclusive_or_expression:
        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 @@ inclusive_or_expression:
        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 @@ logical_and_expression:
        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_xor_expression:
        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_or_expression:
        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 @@ conditional_expression:
        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 @@ assignment_expression:
        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:
        }
        | 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_with_parameters:
 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 @@ function_header:
 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_declaration:
        }
        | 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 @@ init_declarator_list:
        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:
        }
        | 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:
        }
        | 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:
        }
        | 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:
        }
        | 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:
        }
        | 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 @@ init_declarator_list:
 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 @@ single_declaration:
 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_no_prec:
 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 @@ precision_qualifier:
 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_list:
 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_list:
 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 @@ simple_statement:
 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 @@ statement_no_new_scope:
 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 @@ statement_list:
 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 @@ expression_statement:
 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_matched:
 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 @@ condition:
        }
        | 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 @@ case_label:
 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 @@ for_rest_statement:
 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 @@ external_declaration:
 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;