aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2010-04-07 16:46:25 -0700
committerIan Romanick <[email protected]>2010-04-07 16:49:25 -0700
commite701761cc84a136c2e1b3cf341bc0edb90492278 (patch)
tree808b619ec9bb320eaf77b5343c2dbdc8da8ab3b2
parentae4c4c07959f059e557ea44e98552ced1fec9f47 (diff)
Begin processing #extension directive
Nowhere near complete. It just parses correctly at this point.
-rw-r--r--glsl_parser.ypp18
-rw-r--r--glsl_parser_extras.cpp47
-rw-r--r--glsl_parser_extras.h12
3 files changed, 75 insertions, 2 deletions
diff --git a/glsl_parser.ypp b/glsl_parser.ypp
index b8c01b508d0..250c51c7ee3 100644
--- a/glsl_parser.ypp
+++ b/glsl_parser.ypp
@@ -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
{
diff --git a/glsl_parser_extras.cpp b/glsl_parser_extras.cpp
index 335a058b965..1eac1890afe 100644
--- a/glsl_parser_extras.cpp
+++ b/glsl_parser_extras.cpp
@@ -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 */
diff --git a/glsl_parser_extras.h b/glsl_parser_extras.h
index 2f33bea0534..15667ebb689 100644
--- a/glsl_parser_extras.h
+++ b/glsl_parser_extras.h
@@ -86,6 +86,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
*/
extern const char *