[Mesa-dev] [PATCH] RFC: glsl/glcpp: Allow for '#' characters to appear in shader body
Carl Worth
cworth at cworth.org
Thu Jul 31 11:22:59 PDT 2014
Strictly speaking, the GLSL specification only allows for the '#' to appear in
a shader in two places:
1. To introduce a pre-processing directive
In this case, the '#' must be the first character on a line after
ignoring any comments and horizontal whitespace.
2. As part of the token-pasting operator
In this case, the '#' must appear as part of the sequence "##" and
can only appear in the replacement list of a macro definition.
Since commit f062f0506a5b827667b7eb52136d8420b7e8113b, glcpp has been strict
about '#' characters, such that any occurence outside of either of the above
two cases would result in a syntax error of "Unexpected HASH_TOKEN" from the
grammar.
(Prior to that commit, these illegal '#' would be silently ignored and printed
to stdout. And if it hadn't been for that commit, these illegal '#' would have
triggered internal errors with later commits.)
With this commit, glcpp relaxes its strictness and treats such appearances of
'#' as just another piece of punctuation. This would make it legal to do
something like:
#define FOO # something here
and then use "#ifdef FOO" and similar, (though if FOO were ever directly
expanded, this should trigger a syntax error in the main GLSL compiler).
Relaxing strict conformance compared to GLSL seems somewhat dubious here, but
might be justified for a few reasons:
1. GCC's preprocessor allows this, (though C is not GLSL, of course)
2. glcpp is generally soft about illegal characters, (compare to
non-ASCII characters which glcpp happily passes through, trusting
the GLSL compiler to catch them).
3. At least one game in the wild (Reactive Quake) has been observed
with a bogus '#' in it:
#define USE_DISCARD#line 0
Note that the shader (that we've seen) with this line does not ever
*use* the USE_DISCARD macro. Note also that this shader is accepted
by both Nvidia's OpenGL implementation as well as Mesa prior to
the commit referenced above.
---
src/glsl/glcpp/glcpp-lex.l | 12 +++++++-----
src/glsl/glcpp/glcpp-parse.y | 1 +
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/glsl/glcpp/glcpp-lex.l b/src/glsl/glcpp/glcpp-lex.l
index c126850..cf517ad 100644
--- a/src/glsl/glcpp/glcpp-lex.l
+++ b/src/glsl/glcpp/glcpp-lex.l
@@ -270,15 +270,17 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
/* If the '#' is the first non-whitespace, non-comment token on this
* line, then it introduces a directive, switch to the <HASH> start
- * condition.
+ * condition and return a HASH_TOKEN token.
*
- * Otherwise, this is just punctuation, so return the HASH_TOKEN
- * token. */
+ * Otherwise, this is just punctuation, so just return a literal '#'
+ * token, (which will not be interpreted as a directive).
+ */
if (parser->first_non_space_token_this_line) {
BEGIN HASH;
+ RETURN_TOKEN_NEVER_SKIP (HASH_TOKEN);
+ } else {
+ RETURN_TOKEN ('#');
}
-
- RETURN_TOKEN_NEVER_SKIP (HASH_TOKEN);
}
<HASH>version{HSPACE}+ {
diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y
index 4ee4110..b281b01 100644
--- a/src/glsl/glcpp/glcpp-parse.y
+++ b/src/glsl/glcpp/glcpp-parse.y
@@ -744,6 +744,7 @@ operator:
| PASTE { $$ = PASTE; }
| PLUS_PLUS { $$ = PLUS_PLUS; }
| MINUS_MINUS { $$ = MINUS_MINUS; }
+| '#' { $$ = '#'; }
;
%%
--
2.0.0
More information about the mesa-dev
mailing list