Begin processing #extension directive
authorIan Romanick <ian.d.romanick@intel.com>
Wed, 7 Apr 2010 23:46:25 +0000 (16:46 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Wed, 7 Apr 2010 23:49:25 +0000 (16:49 -0700)
Nowhere near complete.  It just parses correctly at this point.

glsl_parser.ypp
glsl_parser_extras.cpp
glsl_parser_extras.h

index b8c01b508d0ddc0bb5434abe69c678e2f67b4fd6..250c51c7ee3feb4e6e204cc00c30e2f47ce6c60e 100644 (file)
@@ -190,13 +190,13 @@ translation_unit:
        {
           _mesa_glsl_initialize_types(state);
        }
-       external_declaration_list
+       extension_statement_list external_declaration_list
        |
        {
           state->language_version = 110;
           _mesa_glsl_initialize_types(state);
        }
-       external_declaration_list
+       extension_statement_list external_declaration_list
        ;
 
 version_statement:
@@ -217,6 +217,20 @@ version_statement:
        }
        ;
 
+extension_statement_list:
+
+       | extension_statement_list extension_statement
+       ;
+
+extension_statement:
+       EXTENSION IDENTIFIER COLON IDENTIFIER EOL
+       {
+          if (!_mesa_glsl_process_extension($2, & @2, $4, & @4, state)) {
+             YYERROR;
+          }
+       }
+       ;
+
 external_declaration_list:
        external_declaration
        {
index 335a058b965cbcfbbc1354162ddbcc1f9463f1b5..1eac1890afe3fa3b34d206826e952cd7eef626ef 100644 (file)
@@ -71,6 +71,53 @@ _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
 }
 
 
+bool
+_mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
+                            const char *behavior, YYLTYPE *behavior_locp,
+                            _mesa_glsl_parse_state *state)
+{
+   enum {
+      extension_disable,
+      extension_enable,
+      extension_require,
+      extension_warn
+   } ext_mode;
+   bool error = false;
+
+   if (strcmp(behavior, "warn") == 0) {
+      ext_mode = extension_warn;
+   } else if (strcmp(behavior, "require") == 0) {
+      ext_mode = extension_require;
+   } else if (strcmp(behavior, "enable") == 0) {
+      ext_mode = extension_enable;
+   } else if (strcmp(behavior, "disable") == 0) {
+      ext_mode = extension_disable;
+   } else {
+      _mesa_glsl_error(behavior_locp, state,
+                      "Unknown extension behavior `%s'",
+                      behavior);
+      return false;
+   }
+
+   if (strcmp(name, "all") == 0) {
+      if ((ext_mode == extension_enable) || (ext_mode == extension_require)) {
+        _mesa_glsl_error(name_locp, state, "Cannot %s all extensions",
+                         (ext_mode == extension_enable)
+                         ? "enable" : "require");
+        return false;
+      }
+   } else {
+      if (ext_mode == extension_require) {
+        _mesa_glsl_error(name_locp, state, "Unknown extension `%s'",
+                         name);
+        return false;
+      }
+   }
+
+   return true;
+}
+
+
 ast_node::~ast_node()
 {
    /* empty */
index 2f33bea0534e60cd8306c347aee8348222f55dde..15667ebb689f9e167a6b0e94965c7f2c8dd59931 100644 (file)
@@ -85,6 +85,18 @@ extern int _mesa_glsl_lex(union YYSTYPE *yylval, YYLTYPE *yylloc,
 
 extern int _mesa_glsl_parse(struct _mesa_glsl_parse_state *);
 
+/**
+ * Process elements of the #extension directive
+ *
+ * \return
+ * If \c name and \c behavior are valid, \c true is returned.  Otherwise
+ * \c false is returned.
+ */
+extern bool _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
+                                        const char *behavior,
+                                        YYLTYPE *behavior_locp,
+                                        _mesa_glsl_parse_state *state);
+
 /**
  * Get the textual name of the specified shader target
  */