From: Marek Olšák <marek.ol...@amd.com> --- src/compiler/glsl/glcpp/glcpp-lex.l | 2 +- src/compiler/glsl/glcpp/glcpp-parse.y | 203 +++++++++++++++------------------- src/compiler/glsl/glcpp/glcpp.h | 1 + 3 files changed, 94 insertions(+), 112 deletions(-)
diff --git a/src/compiler/glsl/glcpp/glcpp-lex.l b/src/compiler/glsl/glcpp/glcpp-lex.l index d09441a..f4a6876 100644 --- a/src/compiler/glsl/glcpp/glcpp-lex.l +++ b/src/compiler/glsl/glcpp/glcpp-lex.l @@ -94,21 +94,21 @@ void glcpp_set_column (int column_no , yyscan_t yyscanner); #define RETURN_TOKEN(token) \ do { \ if (! parser->skipping) { \ RETURN_TOKEN_NEVER_SKIP(token); \ } \ } while(0) #define RETURN_STRING_TOKEN(token) \ do { \ if (! parser->skipping) { \ - yylval->str = ralloc_strdup (yyextra, yytext); \ + yylval->str = linear_strdup(yyextra->linalloc, yytext); \ RETURN_TOKEN_NEVER_SKIP (token); \ } \ } while(0) /* Update all state necessary for each token being returned. * * Here we'll be tracking newlines and spaces so that the lexer can * alter its behavior as necessary, (for example, '#' has special * significance if it is the first non-whitespace, non-comment token diff --git a/src/compiler/glsl/glcpp/glcpp-parse.y b/src/compiler/glsl/glcpp/glcpp-parse.y index 4fd1448..d2081b3 100644 --- a/src/compiler/glsl/glcpp/glcpp-parse.y +++ b/src/compiler/glsl/glcpp/glcpp-parse.y @@ -42,61 +42,62 @@ _define_object_macro(glcpp_parser_t *parser, token_list_t *replacements); static void _define_function_macro(glcpp_parser_t *parser, YYLTYPE *loc, const char *macro, string_list_t *parameters, token_list_t *replacements); static string_list_t * -_string_list_create(void *ctx); +_string_list_create(glcpp_parser_t *parser); static void -_string_list_append_item(string_list_t *list, const char *str); +_string_list_append_item(glcpp_parser_t *parser, string_list_t *list, + const char *str); static int _string_list_contains(string_list_t *list, const char *member, int *index); static const char * _string_list_has_duplicate(string_list_t *list); static int _string_list_length(string_list_t *list); static int _string_list_equal(string_list_t *a, string_list_t *b); static argument_list_t * -_argument_list_create(void *ctx); +_argument_list_create(glcpp_parser_t *parser); static void -_argument_list_append(argument_list_t *list, token_list_t *argument); +_argument_list_append(glcpp_parser_t *parser, argument_list_t *list, + token_list_t *argument); static int _argument_list_length(argument_list_t *list); static token_list_t * _argument_list_member_at(argument_list_t *list, int index); -/* Note: This function ralloc_steal()s the str pointer. */ static token_t * -_token_create_str(void *ctx, int type, char *str); +_token_create_str(glcpp_parser_t *parser, int type, char *str); static token_t * -_token_create_ival(void *ctx, int type, int ival); +_token_create_ival(glcpp_parser_t *parser, int type, int ival); static token_list_t * -_token_list_create(void *ctx); +_token_list_create(glcpp_parser_t *parser); static void -_token_list_append(token_list_t *list, token_t *token); +_token_list_append(glcpp_parser_t *parser, token_list_t *list, token_t *token); static void _token_list_append_list(token_list_t *list, token_list_t *tail); static int _token_list_equal_ignoring_space(token_list_t *a, token_list_t *b); static void _parser_active_list_push(glcpp_parser_t *parser, const char *identifier, token_node_t *marker); @@ -202,21 +203,20 @@ input: /* empty */ | input line ; line: control_line | SPACE control_line | text_line { _glcpp_parser_print_expanded_token_list (parser, $1); ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n"); - ralloc_free ($1); } | expanded_line ; expanded_line: IF_EXPANDED expression NEWLINE { if (parser->is_gles && $2.undefined_macro) glcpp_error(& @1, parser, "undefined macro %s in expression (illegal in GLES)", $2.undefined_macro); _glcpp_parser_skip_stack_push_if (parser, & @1, $2.value); } @@ -270,21 +270,20 @@ control_line: _glcpp_parser_expand_and_lex_from (parser, LINE_EXPANDED, $3, EXPANSION_MODE_IGNORE_DEFINED); } } ; control_line_success: HASH_TOKEN DEFINE_TOKEN define | HASH_TOKEN UNDEF IDENTIFIER NEWLINE { - macro_t *macro; struct hash_entry *entry; /* Section 3.4 (Preprocessor) of the GLSL ES 3.00 spec says: * * It is an error to undefine or to redefine a built-in * (pre-defined) macro name. * * The GLSL ES 1.00 spec does not contain this text. * * Section 3.3 (Preprocessor) of the GLSL 1.30 spec says: @@ -305,25 +304,22 @@ control_line_success: parser->version >= 300 && (strcmp("__LINE__", $3) == 0 || strcmp("__FILE__", $3) == 0 || strcmp("__VERSION__", $3) == 0 || strncmp("GL_", $3, 3) == 0)) glcpp_error(& @1, parser, "Built-in (pre-defined)" " macro names cannot be undefined."); entry = _mesa_hash_table_search (parser->defines, $3); if (entry) { - macro = entry->data; _mesa_hash_table_remove (parser->defines, entry); - ralloc_free (macro); } - ralloc_free ($3); } | HASH_TOKEN IF pp_tokens NEWLINE { /* Be careful to only evaluate the 'if' expression if * we are not skipping. When we are skipping, we * simply push a new 0-valued 'if' onto the skip * stack. * * This avoids generating diagnostics for invalid * expressions that are being skipped. */ if (parser->skip_stack == NULL || @@ -346,21 +342,20 @@ control_line_success: parser->skip_stack->type == SKIP_NO_SKIP) { glcpp_error(& @1, parser, "#if with no expression"); } _glcpp_parser_skip_stack_push_if (parser, & @1, 0); } | HASH_TOKEN IFDEF IDENTIFIER junk NEWLINE { struct hash_entry *entry = _mesa_hash_table_search(parser->defines, $3); macro_t *macro = entry ? entry->data : NULL; - ralloc_free ($3); _glcpp_parser_skip_stack_push_if (parser, & @1, macro != NULL); } | HASH_TOKEN IFNDEF IDENTIFIER junk NEWLINE { struct hash_entry *entry = _mesa_hash_table_search(parser->defines, $3); macro_t *macro = entry ? entry->data : NULL; _glcpp_parser_skip_stack_push_if (parser, & @3, macro == NULL); } | HASH_TOKEN ELIF pp_tokens NEWLINE { /* Be careful to only evaluate the 'elif' expression @@ -471,21 +466,21 @@ integer_constant: } expression: integer_constant { $$.value = $1; $$.undefined_macro = NULL; } | IDENTIFIER { $$.value = 0; if (parser->is_gles) - $$.undefined_macro = ralloc_strdup (parser, $1); + $$.undefined_macro = linear_strdup(parser->linalloc, $1); else $$.undefined_macro = NULL; } | expression OR expression { $$.value = $1.value || $3.value; /* Short-circuit: Only flag undefined from right side * if left side evaluates to false. */ if ($1.undefined_macro) @@ -643,27 +638,25 @@ expression: $$.undefined_macro = $2.undefined_macro; } | '(' expression ')' { $$ = $2; } ; identifier_list: IDENTIFIER { $$ = _string_list_create (parser); - _string_list_append_item ($$, $1); - ralloc_steal ($$, $1); + _string_list_append_item (parser, $$, $1); } | identifier_list ',' IDENTIFIER { $$ = $1; - _string_list_append_item ($$, $3); - ralloc_steal ($$, $3); + _string_list_append_item (parser, $$, $3); } ; text_line: NEWLINE { $$ = NULL; } | pp_tokens NEWLINE ; replacement_list: /* empty */ { $$ = NULL; } @@ -674,25 +667,25 @@ junk: /* empty */ | pp_tokens { glcpp_error(&@1, parser, "extra tokens at end of directive"); } ; pp_tokens: preprocessing_token { parser->space_tokens = 1; $$ = _token_list_create (parser); - _token_list_append ($$, $1); + _token_list_append (parser, $$, $1); } | pp_tokens preprocessing_token { $$ = $1; - _token_list_append ($$, $2); + _token_list_append (parser, $$, $2); } ; preprocessing_token: IDENTIFIER { $$ = _token_create_str (parser, IDENTIFIER, $1); $$->location = yylloc; } | INTEGER_STRING { $$ = _token_create_str (parser, INTEGER_STRING, $1); @@ -748,38 +741,39 @@ operator: | ',' { $$ = ','; } | '=' { $$ = '='; } | PASTE { $$ = PASTE; } | PLUS_PLUS { $$ = PLUS_PLUS; } | MINUS_MINUS { $$ = MINUS_MINUS; } ; %% string_list_t * -_string_list_create(void *ctx) +_string_list_create(glcpp_parser_t *parser) { string_list_t *list; - list = ralloc (ctx, string_list_t); + list = linear_alloc_child(parser->linalloc, sizeof(string_list_t)); list->head = NULL; list->tail = NULL; return list; } void -_string_list_append_item(string_list_t *list, const char *str) +_string_list_append_item(glcpp_parser_t *parser, string_list_t *list, + const char *str) { string_node_t *node; - node = ralloc (list, string_node_t); - node->str = ralloc_strdup (node, str); + node = linear_alloc_child(parser->linalloc, sizeof(string_node_t)); + node->str = linear_strdup(parser->linalloc, str); node->next = NULL; if (list->head == NULL) { list->head = node; } else { list->tail->next = node; } list->tail = node; @@ -858,37 +852,38 @@ _string_list_equal(string_list_t *a, string_list_t *b) return 0; } /* Catch the case of lists being different lengths, (which * would cause the loop above to terminate after the shorter * list). */ return node_a == node_b; } argument_list_t * -_argument_list_create(void *ctx) +_argument_list_create(glcpp_parser_t *parser) { argument_list_t *list; - list = ralloc (ctx, argument_list_t); + list = linear_alloc_child(parser->linalloc, sizeof(argument_list_t)); list->head = NULL; list->tail = NULL; return list; } void -_argument_list_append(argument_list_t *list, token_list_t *argument) +_argument_list_append(glcpp_parser_t *parser, + argument_list_t *list, token_list_t *argument) { argument_node_t *node; - node = ralloc (list, argument_node_t); + node = linear_alloc_child(parser->linalloc, sizeof(argument_node_t)); node->argument = argument; node->next = NULL; if (list->head == NULL) { list->head = node; } else { list->tail->next = node; } @@ -925,66 +920,63 @@ _argument_list_member_at(argument_list_t *list, int index) if (node == NULL) break; } if (node) return node->argument; return NULL; } -/* Note: This function ralloc_steal()s the str pointer. */ token_t * -_token_create_str(void *ctx, int type, char *str) +_token_create_str(glcpp_parser_t *parser, int type, char *str) { token_t *token; - token = ralloc (ctx, token_t); + token = linear_alloc_child(parser->linalloc, sizeof(token_t)); token->type = type; token->value.str = str; - ralloc_steal (token, str); - return token; } token_t * -_token_create_ival(void *ctx, int type, int ival) +_token_create_ival(glcpp_parser_t *parser, int type, int ival) { token_t *token; - token = ralloc (ctx, token_t); + token = linear_alloc_child(parser->linalloc, sizeof(token_t)); token->type = type; token->value.ival = ival; return token; } token_list_t * -_token_list_create(void *ctx) +_token_list_create(glcpp_parser_t *parser) { token_list_t *list; - list = ralloc (ctx, token_list_t); + list = linear_alloc_child(parser->linalloc, sizeof(token_list_t)); list->head = NULL; list->tail = NULL; list->non_space_tail = NULL; return list; } void -_token_list_append(token_list_t *list, token_t *token) +_token_list_append(glcpp_parser_t *parser, token_list_t *list, token_t *token) { token_node_t *node; - node = ralloc (list, token_node_t); + node = linear_alloc_child(parser->linalloc, sizeof(token_node_t)); node->token = token; node->next = NULL; if (list->head == NULL) { list->head = node; } else { list->tail->next = node; } list->tail = node; @@ -1002,51 +994,50 @@ _token_list_append_list(token_list_t *list, token_list_t *tail) list->head = tail->head; } else { list->tail->next = tail->head; } list->tail = tail->tail; list->non_space_tail = tail->non_space_tail; } static token_list_t * -_token_list_copy(void *ctx, token_list_t *other) +_token_list_copy(glcpp_parser_t *parser, token_list_t *other) { token_list_t *copy; token_node_t *node; if (other == NULL) return NULL; - copy = _token_list_create (ctx); + copy = _token_list_create (parser); for (node = other->head; node; node = node->next) { - token_t *new_token = ralloc (copy, token_t); + token_t *new_token = linear_alloc_child(parser->linalloc, sizeof(token_t)); *new_token = *node->token; - _token_list_append (copy, new_token); + _token_list_append (parser, copy, new_token); } return copy; } static void _token_list_trim_trailing_space(token_list_t *list) { token_node_t *tail, *next; if (list->non_space_tail) { tail = list->non_space_tail->next; list->non_space_tail->next = NULL; list->tail = list->non_space_tail; while (tail) { next = tail->next; - ralloc_free (tail); tail = next; } } } static int _token_list_is_empty_ignoring_space(token_list_t *l) { token_node_t *n; @@ -1177,69 +1168,70 @@ _token_print(char **out, size_t *len, token_t *token) case PLACEHOLDER: /* Nothing to print. */ break; default: assert(!"Error: Don't know how to print token."); break; } } -/* Return a new token (ralloc()ed off of 'token') formed by pasting - * 'token' and 'other'. Note that this function may return 'token' or - * 'other' directly rather than allocating anything new. +/* Return a new token formed by pasting 'token' and 'other'. Note that this + * function may return 'token' or 'other' directly rather than allocating + * anything new. * * Caution: Only very cursory error-checking is performed to see if * the final result is a valid single token. */ static token_t * -_token_paste(glcpp_parser_t *parser, token_t *token, token_t *other) +_token_paste(glcpp_parser_t *parser, token_list_t *list, token_t *token, + token_t *other) { token_t *combined = NULL; /* Pasting a placeholder onto anything makes no change. */ if (other->type == PLACEHOLDER) return token; /* When 'token' is a placeholder, just return 'other'. */ if (token->type == PLACEHOLDER) return other; /* A very few single-character punctuators can be combined * with another to form a multi-character punctuator. */ switch (token->type) { case '<': if (other->type == '<') - combined = _token_create_ival (token, LEFT_SHIFT, LEFT_SHIFT); + combined = _token_create_ival (parser, LEFT_SHIFT, LEFT_SHIFT); else if (other->type == '=') - combined = _token_create_ival (token, LESS_OR_EQUAL, LESS_OR_EQUAL); + combined = _token_create_ival (parser, LESS_OR_EQUAL, LESS_OR_EQUAL); break; case '>': if (other->type == '>') - combined = _token_create_ival (token, RIGHT_SHIFT, RIGHT_SHIFT); + combined = _token_create_ival (parser, RIGHT_SHIFT, RIGHT_SHIFT); else if (other->type == '=') - combined = _token_create_ival (token, GREATER_OR_EQUAL, GREATER_OR_EQUAL); + combined = _token_create_ival (parser, GREATER_OR_EQUAL, GREATER_OR_EQUAL); break; case '=': if (other->type == '=') - combined = _token_create_ival (token, EQUAL, EQUAL); + combined = _token_create_ival (parser, EQUAL, EQUAL); break; case '!': if (other->type == '=') - combined = _token_create_ival (token, NOT_EQUAL, NOT_EQUAL); + combined = _token_create_ival (parser, NOT_EQUAL, NOT_EQUAL); break; case '&': if (other->type == '&') - combined = _token_create_ival (token, AND, AND); + combined = _token_create_ival (parser, AND, AND); break; case '|': if (other->type == '|') - combined = _token_create_ival (token, OR, OR); + combined = _token_create_ival (parser, OR, OR); break; } if (combined != NULL) { /* Inherit the location from the first token */ combined->location = token->location; return combined; } /* Two string-valued (or integer) tokens can usually just be @@ -1269,37 +1261,37 @@ _token_paste(glcpp_parser_t *parser, token_t *token, token_t *other) case INTEGER: if (other->value.ival < 0) goto FAIL; break; default: goto FAIL; } } if (token->type == INTEGER) - str = ralloc_asprintf (token, "%" PRIiMAX, token->value.ival); + str = linear_asprintf(parser->linalloc, "%" PRIiMAX, token->value.ival); else - str = ralloc_strdup (token, token->value.str); + str = linear_strdup(parser->linalloc, token->value.str); if (other->type == INTEGER) - ralloc_asprintf_append (&str, "%" PRIiMAX, other->value.ival); + linear_asprintf_append(parser->linalloc, &str, "%" PRIiMAX, other->value.ival); else - ralloc_strcat (&str, other->value.str); + linear_strcat(parser->linalloc, &str, other->value.str); /* New token is same type as original token, unless we * started with an integer, in which case we will be * creating an integer-string. */ combined_type = token->type; if (combined_type == INTEGER) combined_type = INTEGER_STRING; - combined = _token_create_str (token, combined_type, str); + combined = _token_create_str (parser, combined_type, str); combined->location = token->location; return combined; } FAIL: glcpp_error (&token->location, parser, ""); ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "Pasting \""); _token_print (&parser->info_log, &parser->info_log_length, token); ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "\" and \""); _token_print (&parser->info_log, &parser->info_log_length, other); @@ -1328,34 +1320,35 @@ yyerror(YYLTYPE *locp, glcpp_parser_t *parser, const char *error) static void add_builtin_define(glcpp_parser_t *parser, const char *name, int value) { token_t *tok; token_list_t *list; tok = _token_create_ival (parser, INTEGER, value); list = _token_list_create(parser); - _token_list_append(list, tok); + _token_list_append(parser, list, tok); _define_object_macro(parser, NULL, name, list); } glcpp_parser_t * glcpp_parser_create(glcpp_extension_iterator extensions, void *state, gl_api api) { glcpp_parser_t *parser; parser = ralloc (NULL, glcpp_parser_t); glcpp_lex_init_extra (parser, &parser->scanner); parser->defines = _mesa_hash_table_create(NULL, _mesa_key_hash_string, _mesa_key_string_equal); + parser->linalloc = linear_alloc_parent(parser, 0); parser->active = NULL; parser->lexing_directive = 0; parser->space_tokens = 1; parser->last_token_was_newline = 0; parser->last_token_was_space = 0; parser->first_non_space_token_this_line = 1; parser->newline_as_space = 0; parser->in_control_line = 0; parser->paren_count = 0; parser->commented_newlines = 0; @@ -1417,94 +1410,95 @@ typedef enum function_status * FUNCTION_NOT_A_FUNCTION: * * Macro name not followed by a '('. This is not an error, but * simply that the macro name should be treated as a non-macro. * * FUNCTION_UNBALANCED_PARENTHESES * * Macro name is not followed by a balanced set of parentheses. */ static function_status_t -_arguments_parse(argument_list_t *arguments, token_node_t *node, +_arguments_parse(glcpp_parser_t *parser, + argument_list_t *arguments, token_node_t *node, token_node_t **last) { token_list_t *argument; int paren_count; node = node->next; /* Ignore whitespace before first parenthesis. */ while (node && node->token->type == SPACE) node = node->next; if (node == NULL || node->token->type != '(') return FUNCTION_NOT_A_FUNCTION; node = node->next; - argument = _token_list_create (arguments); - _argument_list_append (arguments, argument); + argument = _token_list_create (parser); + _argument_list_append (parser, arguments, argument); for (paren_count = 1; node; node = node->next) { if (node->token->type == '(') { paren_count++; } else if (node->token->type == ')') { paren_count--; if (paren_count == 0) break; } if (node->token->type == ',' && paren_count == 1) { _token_list_trim_trailing_space (argument); - argument = _token_list_create (arguments); - _argument_list_append (arguments, argument); + argument = _token_list_create (parser); + _argument_list_append (parser, arguments, argument); } else { if (argument->head == NULL) { /* Don't treat initial whitespace as part of the argument. */ if (node->token->type == SPACE) continue; } - _token_list_append (argument, node->token); + _token_list_append(parser, argument, node->token); } } if (paren_count) return FUNCTION_UNBALANCED_PARENTHESES; *last = node; return FUNCTION_STATUS_SUCCESS; } static token_list_t * -_token_list_create_with_one_ival(void *ctx, int type, int ival) +_token_list_create_with_one_ival(glcpp_parser_t *parser, int type, int ival) { token_list_t *list; token_t *node; - list = _token_list_create(ctx); - node = _token_create_ival(list, type, ival); - _token_list_append(list, node); + list = _token_list_create(parser); + node = _token_create_ival(parser, type, ival); + _token_list_append(parser, list, node); return list; } static token_list_t * -_token_list_create_with_one_space(void *ctx) +_token_list_create_with_one_space(glcpp_parser_t *parser) { - return _token_list_create_with_one_ival(ctx, SPACE, SPACE); + return _token_list_create_with_one_ival(parser, SPACE, SPACE); } static token_list_t * -_token_list_create_with_one_integer(void *ctx, int ival) +_token_list_create_with_one_integer(glcpp_parser_t *parser, int ival) { - return _token_list_create_with_one_ival(ctx, INTEGER, ival); + return _token_list_create_with_one_ival(parser, INTEGER, ival); } /* Evaluate a DEFINED token node (based on subsequent tokens in the list). * * Note: This function must only be called when "node" is a DEFINED token, * (and will abort with an assertion failure otherwise). * * If "node" is followed, (ignoring any SPACE tokens), by an IDENTIFIER token * (optionally preceded and followed by '(' and ')' tokens) then the following * occurs: @@ -1594,22 +1588,22 @@ _glcpp_parser_evaluate_defined_in_list(glcpp_parser_t *parser, while (node) { if (node->token->type != DEFINED) goto NEXT; value = _glcpp_parser_evaluate_defined (parser, node, &last); if (value == -1) goto NEXT; - replacement = ralloc (list, token_node_t); - replacement->token = _token_create_ival (list, INTEGER, value); + replacement = linear_alloc_child(parser->linalloc, sizeof(token_node_t)); + replacement->token = _token_create_ival (parser, INTEGER, value); /* Splice replacement node into list, replacing from "node" * through "last". */ if (node_prev) node_prev->next = replacement; else list->head = replacement; replacement->next = last->next; if (last == list->tail) list->tail = replacement; @@ -1632,21 +1626,21 @@ _glcpp_parser_evaluate_defined_in_list(glcpp_parser_t *parser, */ static void _glcpp_parser_expand_and_lex_from(glcpp_parser_t *parser, int head_token_type, token_list_t *list, expansion_mode_t mode) { token_list_t *expanded; token_t *token; expanded = _token_list_create (parser); token = _token_create_ival (parser, head_token_type, head_token_type); - _token_list_append (expanded, token); + _token_list_append (parser, expanded, token); _glcpp_parser_expand_token_list (parser, list, mode); _token_list_append_list (expanded, list); glcpp_parser_lex_from (parser, expanded); } static void _glcpp_parser_apply_pastes(glcpp_parser_t *parser, token_list_t *list) { token_node_t *node; @@ -1670,21 +1664,21 @@ _glcpp_parser_apply_pastes(glcpp_parser_t *parser, token_list_t *list) /* Now find the next non-space token after the PASTE. */ next_non_space = next_non_space->next; while (next_non_space && next_non_space->token->type == SPACE) next_non_space = next_non_space->next; if (next_non_space == NULL) { yyerror(&node->token->location, parser, "'##' cannot appear at either end of a macro expansion\n"); return; } - node->token = _token_paste(parser, node->token, next_non_space->token); + node->token = _token_paste(parser, list, node->token, next_non_space->token); node->next = next_non_space->next; if (next_non_space == list->tail) list->tail = node; } list->non_space_tail = list->tail; } /* This is a helper function that's essentially part of the * implementation of _glcpp_parser_expand_node. It shouldn't be called @@ -1719,75 +1713,74 @@ _glcpp_parser_expand_function(glcpp_parser_t *parser, token_node_t *node, int parameter_index; identifier = node->token->value.str; entry = _mesa_hash_table_search(parser->defines, identifier); macro = entry ? entry->data : NULL; assert(macro->is_function); arguments = _argument_list_create(parser); - status = _arguments_parse(arguments, node, last); + status = _arguments_parse(parser, arguments, node, last); switch (status) { case FUNCTION_STATUS_SUCCESS: break; case FUNCTION_NOT_A_FUNCTION: return NULL; case FUNCTION_UNBALANCED_PARENTHESES: glcpp_error(&node->token->location, parser, "Macro %s call has unbalanced parentheses\n", identifier); return NULL; } /* Replace a macro defined as empty with a SPACE token. */ if (macro->replacements == NULL) { - ralloc_free(arguments); return _token_list_create_with_one_space(parser); } if (!((_argument_list_length (arguments) == _string_list_length (macro->parameters)) || (_string_list_length (macro->parameters) == 0 && _argument_list_length (arguments) == 1 && arguments->head->argument->head == NULL))) { glcpp_error(&node->token->location, parser, "Error: macro %s invoked with %d arguments (expected %d)\n", identifier, _argument_list_length (arguments), _string_list_length(macro->parameters)); return NULL; } /* Perform argument substitution on the replacement list. */ - substituted = _token_list_create(arguments); + substituted = _token_list_create(parser); for (node = macro->replacements->head; node; node = node->next) { if (node->token->type == IDENTIFIER && _string_list_contains(macro->parameters, node->token->value.str, ¶meter_index)) { token_list_t *argument; argument = _argument_list_member_at(arguments, parameter_index); /* Before substituting, we expand the argument tokens, or append a * placeholder token for an empty argument. */ if (argument->head) { token_list_t *expanded_argument; expanded_argument = _token_list_copy(parser, argument); _glcpp_parser_expand_token_list(parser, expanded_argument, mode); _token_list_append_list(substituted, expanded_argument); } else { token_t *new_token; - new_token = _token_create_ival(substituted, PLACEHOLDER, + new_token = _token_create_ival(parser, PLACEHOLDER, PLACEHOLDER); - _token_list_append(substituted, new_token); + _token_list_append(parser, substituted, new_token); } } else { - _token_list_append(substituted, node->token); + _token_list_append(parser, substituted, node->token); } } /* After argument substitution, and before further expansion * below, implement token pasting. */ _token_list_trim_trailing_space(substituted); _glcpp_parser_apply_pastes(parser, substituted); @@ -1847,24 +1840,24 @@ _glcpp_parser_expand_node(glcpp_parser_t *parser, token_node_t *node, /* Finally, don't expand this macro if we're already actively * expanding it, (to avoid infinite recursion). */ if (_parser_active_list_contains (parser, identifier)) { /* We change the token type here from IDENTIFIER to OTHER to prevent any * future expansion of this unexpanded token. */ char *str; token_list_t *expansion; token_t *final; - str = ralloc_strdup(parser, token->value.str); + str = linear_strdup(parser->linalloc, token->value.str); final = _token_create_str(parser, OTHER, str); expansion = _token_list_create(parser); - _token_list_append(expansion, final); + _token_list_append(parser, expansion, final); return expansion; } if (! macro->is_function) { token_list_t *replacement; /* Replace a macro defined as empty with a SPACE token. */ if (macro->replacements == NULL) return _token_list_create_with_one_space(parser); @@ -1882,41 +1875,39 @@ _glcpp_parser_expand_node(glcpp_parser_t *parser, token_node_t *node, * expansion of 'identifier'. That is, when the list iterator begins * examining 'marker', then it is time to pop this node from the * active stack. */ static void _parser_active_list_push(glcpp_parser_t *parser, const char *identifier, token_node_t *marker) { active_list_t *node; - node = ralloc(parser->active, active_list_t); - node->identifier = ralloc_strdup(node, identifier); + node = linear_alloc_child(parser->linalloc, sizeof(active_list_t)); + node->identifier = linear_strdup(parser->linalloc, identifier); node->marker = marker; node->next = parser->active; parser->active = node; } static void _parser_active_list_pop(glcpp_parser_t *parser) { active_list_t *node = parser->active; if (node == NULL) { parser->active = NULL; return; } node = parser->active->next; - ralloc_free (parser->active); - parser->active = node; } static int _parser_active_list_contains(glcpp_parser_t *parser, const char *identifier) { active_list_t *node; if (parser->active == NULL) return 0; @@ -2090,33 +2081,31 @@ _define_object_macro(glcpp_parser_t *parser, YYLTYPE *loc, { macro_t *macro, *previous; struct hash_entry *entry; /* We define pre-defined macros before we've started parsing the actual * file. So if there's no location defined yet, that's what were doing and * we don't want to generate an error for using the reserved names. */ if (loc != NULL) _check_for_reserved_macro_name(parser, loc, identifier); - macro = ralloc (parser, macro_t); + macro = linear_alloc_child(parser->linalloc, sizeof(macro_t)); macro->is_function = 0; macro->parameters = NULL; - macro->identifier = ralloc_strdup (macro, identifier); + macro->identifier = linear_strdup(parser->linalloc, identifier); macro->replacements = replacements; - ralloc_steal (macro, replacements); entry = _mesa_hash_table_search(parser->defines, identifier); previous = entry ? entry->data : NULL; if (previous) { if (_macro_equal (macro, previous)) { - ralloc_free (macro); return; } glcpp_error (loc, parser, "Redefinition of macro %s\n", identifier); } _mesa_hash_table_insert (parser->defines, identifier, macro); } void _define_function_macro(glcpp_parser_t *parser, YYLTYPE *loc, @@ -2127,34 +2116,31 @@ _define_function_macro(glcpp_parser_t *parser, YYLTYPE *loc, struct hash_entry *entry; const char *dup; _check_for_reserved_macro_name(parser, loc, identifier); /* Check for any duplicate parameter names. */ if ((dup = _string_list_has_duplicate (parameters)) != NULL) { glcpp_error (loc, parser, "Duplicate macro parameter \"%s\"", dup); } - macro = ralloc (parser, macro_t); - ralloc_steal (macro, parameters); - ralloc_steal (macro, replacements); + macro = linear_alloc_child(parser->linalloc, sizeof(macro_t)); macro->is_function = 1; macro->parameters = parameters; - macro->identifier = ralloc_strdup (macro, identifier); + macro->identifier = linear_strdup(parser->linalloc, identifier); macro->replacements = replacements; entry = _mesa_hash_table_search(parser->defines, identifier); previous = entry ? entry->data : NULL; if (previous) { if (_macro_equal (macro, previous)) { - ralloc_free (macro); return; } glcpp_error (loc, parser, "Redefinition of macro %s\n", identifier); } _mesa_hash_table_insert(parser->defines, identifier, macro); } static int glcpp_parser_lex(YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser) @@ -2207,21 +2193,20 @@ glcpp_parser_lex(YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser) parser->paren_count = 0; } } return ret; } node = parser->lex_from_node; if (node == NULL) { - ralloc_free (parser->lex_from_list); parser->lex_from_list = NULL; return NEWLINE; } *yylval = node->token->value; ret = node->token->type; parser->lex_from_node = node->next; return ret; @@ -2233,45 +2218,42 @@ glcpp_parser_lex_from(glcpp_parser_t *parser, token_list_t *list) token_node_t *node; assert (parser->lex_from_list == NULL); /* Copy list, eliminating any space tokens. */ parser->lex_from_list = _token_list_create (parser); for (node = list->head; node; node = node->next) { if (node->token->type == SPACE) continue; - _token_list_append (parser->lex_from_list, node->token); + _token_list_append (parser, parser->lex_from_list, node->token); } - ralloc_free (list); - parser->lex_from_node = parser->lex_from_list->head; /* It's possible the list consisted of nothing but whitespace. */ if (parser->lex_from_node == NULL) { - ralloc_free (parser->lex_from_list); parser->lex_from_list = NULL; } } static void _glcpp_parser_skip_stack_push_if(glcpp_parser_t *parser, YYLTYPE *loc, int condition) { skip_type_t current = SKIP_NO_SKIP; skip_node_t *node; if (parser->skip_stack) current = parser->skip_stack->type; - node = ralloc (parser, skip_node_t); + node = linear_alloc_child(parser->linalloc, sizeof(skip_node_t)); node->loc = *loc; if (current == SKIP_NO_SKIP) { if (condition) node->type = SKIP_NO_SKIP; else node->type = SKIP_TO_ELSE; } else { node->type = SKIP_TO_ENDIF; } @@ -2303,21 +2285,20 @@ _glcpp_parser_skip_stack_pop(glcpp_parser_t *parser, YYLTYPE *loc) { skip_node_t *node; if (parser->skip_stack == NULL) { glcpp_error (loc, parser, "#endif without #if\n"); return; } node = parser->skip_stack; parser->skip_stack = node->next; - ralloc_free (node); } static void _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version, const char *es_identifier, bool explicitly_set) { if (parser->version != 0) return; diff --git a/src/compiler/glsl/glcpp/glcpp.h b/src/compiler/glsl/glcpp/glcpp.h index cab4374..bb4ad67 100644 --- a/src/compiler/glsl/glcpp/glcpp.h +++ b/src/compiler/glsl/glcpp/glcpp.h @@ -174,20 +174,21 @@ typedef struct active_list { struct _mesa_glsl_parse_state; typedef void (*glcpp_extension_iterator)( struct _mesa_glsl_parse_state *state, void (*add_builtin_define)(glcpp_parser_t *, const char *, int), glcpp_parser_t *data, unsigned version, bool es); struct glcpp_parser { + void *linalloc; yyscan_t scanner; struct hash_table *defines; active_list_t *active; int lexing_directive; int lexing_version_directive; int space_tokens; int last_token_was_newline; int last_token_was_space; int first_non_space_token_this_line; int newline_as_space; -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev