glsl: pass gl_context to glcpp_parser_create()
[mesa.git] / src / compiler / glsl / glcpp / glcpp-parse.y
index f1719f90b11e635b4cc91e857597dd7f290bfd35..4ae78fbf8f27bd248632c0fb629034cba1329ec9 100644 (file)
@@ -29,8 +29,7 @@
 #include <inttypes.h>
 
 #include "glcpp.h"
-#include "main/core.h" /* for struct gl_extensions */
-#include "main/mtypes.h" /* for gl_api enum */
+#include "main/mtypes.h"
 
 static void
 yyerror(YYLTYPE *locp, glcpp_parser_t *parser, const char *error);
@@ -175,11 +174,11 @@ add_builtin_define(glcpp_parser_t *parser, const char *name, int value);
         /* We use HASH_TOKEN, DEFINE_TOKEN and VERSION_TOKEN (as opposed to
          * HASH, DEFINE, and VERSION) to avoid conflicts with other symbols,
          * (such as the <HASH> and <DEFINE> start conditions in the lexer). */
-%token DEFINED ELIF_EXPANDED HASH_TOKEN DEFINE_TOKEN FUNC_IDENTIFIER OBJ_IDENTIFIER ELIF ELSE ENDIF ERROR_TOKEN IF IFDEF IFNDEF LINE PRAGMA UNDEF VERSION_TOKEN GARBAGE IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE PLUS_PLUS MINUS_MINUS
+%token DEFINED ELIF_EXPANDED HASH_TOKEN DEFINE_TOKEN FUNC_IDENTIFIER OBJ_IDENTIFIER ELIF ELSE ENDIF ERROR_TOKEN IF IFDEF IFNDEF LINE PRAGMA UNDEF VERSION_TOKEN GARBAGE IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE PLUS_PLUS MINUS_MINUS PATH
 %token PASTE
 %type <ival> INTEGER operator SPACE integer_constant version_constant
 %type <expression_value> expression
-%type <str> IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER ERROR_TOKEN PRAGMA
+%type <str> IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER ERROR_TOKEN PRAGMA PATH
 %type <string_list> identifier_list
 %type <token> preprocessing_token
 %type <token_list> pp_tokens replacement_list text_line
@@ -209,7 +208,7 @@ line:
 |      SPACE control_line
 |      text_line {
                _glcpp_parser_print_expanded_token_list (parser, $1);
-               ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n");
+               _mesa_string_buffer_append_char(parser->output, '\n');
        }
 |      expanded_line
 ;
@@ -228,20 +227,23 @@ expanded_line:
 |      LINE_EXPANDED integer_constant NEWLINE {
                parser->has_new_line_number = 1;
                parser->new_line_number = $2;
-               ralloc_asprintf_rewrite_tail (&parser->output,
-                                             &parser->output_length,
-                                             "#line %" PRIiMAX "\n",
-                                             $2);
+               _mesa_string_buffer_printf(parser->output, "#line %" PRIiMAX "\n", $2);
        }
 |      LINE_EXPANDED integer_constant integer_constant NEWLINE {
                parser->has_new_line_number = 1;
                parser->new_line_number = $2;
                parser->has_new_source_number = 1;
                parser->new_source_number = $3;
-               ralloc_asprintf_rewrite_tail (&parser->output,
-                                             &parser->output_length,
-                                             "#line %" PRIiMAX " %" PRIiMAX "\n",
-                                             $2, $3);
+               _mesa_string_buffer_printf(parser->output,
+                                          "#line %" PRIiMAX " %" PRIiMAX "\n",
+                                           $2, $3);
+       }
+|      LINE_EXPANDED integer_constant PATH NEWLINE {
+               parser->has_new_line_number = 1;
+               parser->new_line_number = $2;
+               _mesa_string_buffer_printf(parser->output,
+                                          "#line %" PRIiMAX " %s\n",
+                                           $2, $3);
        }
 ;
 
@@ -259,7 +261,7 @@ define:
 
 control_line:
        control_line_success {
-               ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n");
+               _mesa_string_buffer_append_char(parser->output, '\n');
        }
 |      control_line_error
 |      HASH_TOKEN LINE pp_tokens NEWLINE {
@@ -449,7 +451,7 @@ control_line_success:
                glcpp_parser_resolve_implicit_version(parser);
        }
 |      HASH_TOKEN PRAGMA NEWLINE {
-               ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "#%s", $2);
+               _mesa_string_buffer_printf(parser->output, "#%s", $2);
        }
 ;
 
@@ -467,13 +469,8 @@ control_line_error:
 
 integer_constant:
        INTEGER_STRING {
-               if (strlen ($1) >= 3 && strncmp ($1, "0x", 2) == 0) {
-                       $$ = strtoll ($1 + 2, NULL, 16);
-               } else if ($1[0] == '0') {
-                       $$ = strtoll ($1, NULL, 8);
-               } else {
-                       $$ = strtoll ($1, NULL, 10);
-               }
+               /* let strtoll detect the base */
+               $$ = strtoll ($1, NULL, 0);
        }
 |      INTEGER {
                $$ = $1;
@@ -716,6 +713,10 @@ preprocessing_token:
                $$ = _token_create_str (parser, INTEGER_STRING, $1);
                $$->location = yylloc;
        }
+|      PATH {
+               $$ = _token_create_str (parser, PATH, $1);
+               $$->location = yylloc;
+       }
 |      operator {
                $$ = _token_create_ival (parser, $1, $1);
                $$->location = yylloc;
@@ -1084,6 +1085,20 @@ _token_list_equal_ignoring_space(token_list_t *a, token_list_t *b)
 
    while (1)
    {
+      if (node_a == NULL && node_b == NULL)
+         break;
+
+      /* Ignore trailing whitespace */
+      if (node_a == NULL && node_b->token->type == SPACE) {
+         while (node_b && node_b->token->type == SPACE)
+            node_b = node_b->next;
+      }
+
+      if (node_b == NULL && node_a->token->type == SPACE) {
+         while (node_a && node_a->token->type == SPACE)
+            node_a = node_a->next;
+      }
+
       if (node_a == NULL && node_b == NULL)
          break;
 
@@ -1127,60 +1142,60 @@ _token_list_equal_ignoring_space(token_list_t *a, token_list_t *b)
 }
 
 static void
-_token_print(char **out, size_t *len, token_t *token)
+_token_print(struct _mesa_string_buffer *out, token_t *token)
 {
    if (token->type < 256) {
-      ralloc_asprintf_rewrite_tail (out, len, "%c", token->type);
+      _mesa_string_buffer_append_char(out, token->type);
       return;
    }
 
    switch (token->type) {
    case INTEGER:
-      ralloc_asprintf_rewrite_tail (out, len, "%" PRIiMAX, token->value.ival);
+      _mesa_string_buffer_printf(out, "%" PRIiMAX, token->value.ival);
       break;
    case IDENTIFIER:
    case INTEGER_STRING:
    case OTHER:
-      ralloc_asprintf_rewrite_tail (out, len, "%s", token->value.str);
+      _mesa_string_buffer_append(out, token->value.str);
       break;
    case SPACE:
-      ralloc_asprintf_rewrite_tail (out, len, " ");
+      _mesa_string_buffer_append_char(out, ' ');
       break;
    case LEFT_SHIFT:
-      ralloc_asprintf_rewrite_tail (out, len, "<<");
+      _mesa_string_buffer_append(out, "<<");
       break;
    case RIGHT_SHIFT:
-      ralloc_asprintf_rewrite_tail (out, len, ">>");
+      _mesa_string_buffer_append(out, ">>");
       break;
    case LESS_OR_EQUAL:
-      ralloc_asprintf_rewrite_tail (out, len, "<=");
+      _mesa_string_buffer_append(out, "<=");
       break;
    case GREATER_OR_EQUAL:
-      ralloc_asprintf_rewrite_tail (out, len, ">=");
+      _mesa_string_buffer_append(out, ">=");
       break;
    case EQUAL:
-      ralloc_asprintf_rewrite_tail (out, len, "==");
+      _mesa_string_buffer_append(out, "==");
       break;
    case NOT_EQUAL:
-      ralloc_asprintf_rewrite_tail (out, len, "!=");
+      _mesa_string_buffer_append(out, "!=");
       break;
    case AND:
-      ralloc_asprintf_rewrite_tail (out, len, "&&");
+      _mesa_string_buffer_append(out, "&&");
       break;
    case OR:
-      ralloc_asprintf_rewrite_tail (out, len, "||");
+      _mesa_string_buffer_append(out, "||");
       break;
    case PASTE:
-      ralloc_asprintf_rewrite_tail (out, len, "##");
+      _mesa_string_buffer_append(out, "##");
       break;
    case PLUS_PLUS:
-      ralloc_asprintf_rewrite_tail (out, len, "++");
+      _mesa_string_buffer_append(out, "++");
       break;
    case MINUS_MINUS:
-      ralloc_asprintf_rewrite_tail (out, len, "--");
+      _mesa_string_buffer_append(out, "--");
       break;
    case DEFINED:
-      ralloc_asprintf_rewrite_tail (out, len, "defined");
+      _mesa_string_buffer_append(out, "defined");
       break;
    case PLACEHOLDER:
       /* Nothing to print. */
@@ -1307,11 +1322,11 @@ _token_paste(glcpp_parser_t *parser, token_t *token, token_t *other)
 
     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);
-   ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "\" does not give a valid preprocessing token.\n");
+   _mesa_string_buffer_append(parser->info_log, "Pasting \"");
+   _token_print(parser->info_log, token);
+   _mesa_string_buffer_append(parser->info_log, "\" and \"");
+   _token_print(parser->info_log, other);
+   _mesa_string_buffer_append(parser->info_log, "\" does not give a valid preprocessing token.\n");
 
    return token;
 }
@@ -1325,7 +1340,7 @@ _token_list_print(glcpp_parser_t *parser, token_list_t *list)
       return;
 
    for (node = list->head; node; node = node->next)
-      _token_print (&parser->output, &parser->output_length, node->token);
+      _token_print(parser->output, node->token);
 }
 
 void
@@ -1347,9 +1362,14 @@ add_builtin_define(glcpp_parser_t *parser, const char *name, int value)
    _define_object_macro(parser, NULL, name, list);
 }
 
+/* Initial output buffer size, 4096 minus ralloc() overhead. It was selected
+ * to minimize total amount of allocated memory during shader-db run.
+ */
+#define INITIAL_PP_OUTPUT_BUF_SIZE 4048
+
 glcpp_parser_t *
-glcpp_parser_create(const struct gl_extensions *extension_list,
-                    glcpp_extension_iterator extensions, void *state, gl_api api)
+glcpp_parser_create(struct gl_context *gl_ctx,
+                    glcpp_extension_iterator extensions, void *state)
 {
    glcpp_parser_t *parser;
 
@@ -1377,16 +1397,16 @@ glcpp_parser_create(const struct gl_extensions *extension_list,
    parser->lex_from_list = NULL;
    parser->lex_from_node = NULL;
 
-   parser->output = ralloc_strdup(parser, "");
-   parser->output_length = 0;
-   parser->info_log = ralloc_strdup(parser, "");
-   parser->info_log_length = 0;
+   parser->output = _mesa_string_buffer_create(parser,
+                                               INITIAL_PP_OUTPUT_BUF_SIZE);
+   parser->info_log = _mesa_string_buffer_create(parser,
+                                                 INITIAL_PP_OUTPUT_BUF_SIZE);
    parser->error = 0;
 
    parser->extensions = extensions;
-   parser->extension_list = extension_list;
+   parser->extension_list = &gl_ctx->Extensions;
    parser->state = state;
-   parser->api = api;
+   parser->api = gl_ctx->API;
    parser->version = 0;
    parser->version_set = false;
 
@@ -1829,7 +1849,8 @@ _glcpp_parser_expand_function(glcpp_parser_t *parser, token_node_t *node,
  */
 static token_list_t *
 _glcpp_parser_expand_node(glcpp_parser_t *parser, token_node_t *node,
-                          token_node_t **last, expansion_mode_t mode)
+                          token_node_t **last, expansion_mode_t mode,
+                          int line)
 {
    token_t *token = node->token;
    const char *identifier;
@@ -1848,8 +1869,7 @@ _glcpp_parser_expand_node(glcpp_parser_t *parser, token_node_t *node,
     * the hash table). */
    if (*identifier == '_') {
       if (strcmp(identifier, "__LINE__") == 0)
-         return _token_list_create_with_one_integer(parser,
-                                                    node->token->location.first_line);
+         return _token_list_create_with_one_integer(parser, line);
 
       if (strcmp(identifier, "__FILE__") == 0)
          return _token_list_create_with_one_integer(parser,
@@ -1974,12 +1994,15 @@ _glcpp_parser_expand_token_list(glcpp_parser_t *parser, token_list_t *list,
    token_node_t *node, *last = NULL;
    token_list_t *expansion;
    active_list_t *active_initial = parser->active;
+   int line;
 
    if (list == NULL)
       return;
 
    _token_list_trim_trailing_space (list);
 
+   line = list->tail->token->location.last_line;
+
    node_prev = NULL;
    node = list->head;
 
@@ -1991,7 +2014,7 @@ _glcpp_parser_expand_token_list(glcpp_parser_t *parser, token_list_t *list,
       while (parser->active && parser->active->marker == node)
          _parser_active_list_pop (parser);
 
-      expansion = _glcpp_parser_expand_node (parser, node, &last, mode);
+      expansion = _glcpp_parser_expand_node (parser, node, &last, mode, line);
       if (expansion) {
          token_node_t *n;
 
@@ -2322,7 +2345,7 @@ _glcpp_parser_skip_stack_pop(glcpp_parser_t *parser, YYLTYPE *loc)
 
 static void
 _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version,
-                                         const char *es_identifier,
+                                         const char *identifier,
                                          bool explicitly_set)
 {
    if (parser->version_set)
@@ -2334,11 +2357,15 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio
    add_builtin_define (parser, "__VERSION__", version);
 
    parser->is_gles = (version == 100) ||
-                     (es_identifier && (strcmp(es_identifier, "es") == 0));
+                     (identifier && (strcmp(identifier, "es") == 0));
+   bool is_compat = version >= 150 && identifier &&
+                    strcmp(identifier, "compatibility") == 0;
 
    /* Add pre-defined macros. */
    if (parser->is_gles)
       add_builtin_define(parser, "GL_ES", 1);
+   else if (is_compat)
+      add_builtin_define(parser, "GL_compatibility_profile", 1);
    else if (version >= 150)
       add_builtin_define(parser, "GL_core_profile", 1);
 
@@ -2371,10 +2398,10 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio
    }
 
    if (explicitly_set) {
-      ralloc_asprintf_rewrite_tail(&parser->output, &parser->output_length,
-                                   "#version %" PRIiMAX "%s%s", version,
-                                   es_identifier ? " " : "",
-                                   es_identifier ? es_identifier : "");
+      _mesa_string_buffer_printf(parser->output,
+                                 "#version %" PRIiMAX "%s%s", version,
+                                 identifier ? " " : "",
+                                 identifier ? identifier : "");
    }
 }