glsl: pass gl_context to glcpp_parser_create()
[mesa.git] / src / compiler / glsl / glcpp / glcpp-parse.y
index 913bce1fde8b7ee00e31802771b2d94970bf270b..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
@@ -239,6 +238,13 @@ expanded_line:
                                           "#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);
+       }
 ;
 
 define:
@@ -463,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;
@@ -712,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;
@@ -1080,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;
 
@@ -1349,8 +1368,8 @@ add_builtin_define(glcpp_parser_t *parser, const char *name, int value)
 #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;
 
@@ -1385,9 +1404,9 @@ glcpp_parser_create(const struct gl_extensions *extension_list,
    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;
 
@@ -1830,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;
@@ -1849,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,
@@ -1975,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;
 
@@ -1992,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;
 
@@ -2323,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)
@@ -2335,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);
 
@@ -2374,8 +2400,8 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio
    if (explicitly_set) {
       _mesa_string_buffer_printf(parser->output,
                                  "#version %" PRIiMAX "%s%s", version,
-                                 es_identifier ? " " : "",
-                                 es_identifier ? es_identifier : "");
+                                 identifier ? " " : "",
+                                 identifier ? identifier : "");
    }
 }