[Mesa-dev] [PATCH 1/2] glcpp: Allow for conditional conversion of an undefined macro to zero.
Carl Worth
cworth at cworth.org
Thu Nov 22 08:57:51 PST 2012
Previously, the grammar would cause any identifier parsed in a context
expecting an expression to yield an integer value of zero. A future change
will make this behavior conditional, (depending on the GL API). In order to
enable that, we move the macro->0 conversion from the grammar to explicit code
within the _glcpp_parser_expand_node function, made conditional on a new
undefined_macro_mode.
With this change, there's no (intended) behavioral change. The
undefined_macro_mode flag is set to UNDEFINED_MACRO_IS_ZERO only when
expanding an #if or #elif expression. All other expansions will leave the
undefined macro as an identifier.
---
src/glsl/glcpp/glcpp-parse.y | 69 +++++++++++++++++++++++++++++++-----------
1 file changed, 51 insertions(+), 18 deletions(-)
diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y
index f62cbe4..38fe44a 100644
--- a/src/glsl/glcpp/glcpp-parse.y
+++ b/src/glsl/glcpp/glcpp-parse.y
@@ -105,18 +105,31 @@ _parser_active_list_pop (glcpp_parser_t *parser);
static int
_parser_active_list_contains (glcpp_parser_t *parser, const char *identifier);
+/* How should expansion treat identifiers that are not defined macros?
+ *
+ * If the mode is UNDEFINED_MACRO_IS_IDENTIFIER the identifier will be
+ * preserved unchanged. If the mode is UNDEFINED_MACRO_IS_ZERO, the
+ * identifier will be converted into a integer token with value of 0.
+ */
+typedef enum {
+ UNDEFINED_MACRO_IS_IDENTIFIER,
+ UNDEFINED_MACRO_IS_ZERO
+} undefined_macro_mode_t;
+
/* Expand list, and begin lexing from the result (after first
* prefixing a token of type 'head_token_type').
*/
static void
_glcpp_parser_expand_and_lex_from (glcpp_parser_t *parser,
int head_token_type,
- token_list_t *list);
+ token_list_t *list,
+ undefined_macro_mode_t undefined_macro_mode);
/* Perform macro expansion in-place on the given list. */
static void
_glcpp_parser_expand_token_list (glcpp_parser_t *parser,
- token_list_t *list);
+ token_list_t *list,
+ undefined_macro_mode_t undefined_macro_mode);
static void
_glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser,
@@ -199,7 +212,8 @@ line:
parser->skip_stack->type == SKIP_NO_SKIP)
{
_glcpp_parser_expand_and_lex_from (parser,
- LINE_EXPANDED, $2);
+ LINE_EXPANDED, $2,
+ UNDEFINED_MACRO_IS_IDENTIFIER);
}
}
| text_line {
@@ -268,7 +282,8 @@ control_line:
parser->skip_stack->type == SKIP_NO_SKIP)
{
_glcpp_parser_expand_and_lex_from (parser,
- IF_EXPANDED, $2);
+ IF_EXPANDED, $2,
+ UNDEFINED_MACRO_IS_ZERO);
}
else
{
@@ -308,7 +323,8 @@ control_line:
parser->skip_stack->type == SKIP_TO_ELSE)
{
_glcpp_parser_expand_and_lex_from (parser,
- ELIF_EXPANDED, $2);
+ ELIF_EXPANDED, $2,
+ UNDEFINED_MACRO_IS_ZERO);
}
else
{
@@ -362,9 +378,6 @@ integer_constant:
expression:
integer_constant
-| IDENTIFIER {
- $$ = 0;
- }
| expression OR expression {
$$ = $1 || $3;
}
@@ -1309,7 +1322,8 @@ _token_list_create_with_one_space (void *ctx)
static void
_glcpp_parser_expand_and_lex_from (glcpp_parser_t *parser,
int head_token_type,
- token_list_t *list)
+ token_list_t *list,
+ undefined_macro_mode_t undefined_macro_mode)
{
token_list_t *expanded;
token_t *token;
@@ -1317,7 +1331,7 @@ _glcpp_parser_expand_and_lex_from (glcpp_parser_t *parser,
expanded = _token_list_create (parser);
token = _token_create_ival (parser, head_token_type, head_token_type);
_token_list_append (expanded, token);
- _glcpp_parser_expand_token_list (parser, list);
+ _glcpp_parser_expand_token_list (parser, list, undefined_macro_mode);
_token_list_append_list (expanded, list);
glcpp_parser_lex_from (parser, expanded);
}
@@ -1454,7 +1468,8 @@ _glcpp_parser_expand_function (glcpp_parser_t *parser,
expanded_argument = _token_list_copy (parser,
argument);
_glcpp_parser_expand_token_list (parser,
- expanded_argument);
+ expanded_argument,
+ UNDEFINED_MACRO_IS_IDENTIFIER);
_token_list_append_list (substituted,
expanded_argument);
} else {
@@ -1498,7 +1513,8 @@ _glcpp_parser_expand_function (glcpp_parser_t *parser,
static token_list_t *
_glcpp_parser_expand_node (glcpp_parser_t *parser,
token_node_t *node,
- token_node_t **last)
+ token_node_t **last,
+ undefined_macro_mode_t undefined_macro_mode)
{
token_t *token = node->token;
const char *identifier;
@@ -1521,9 +1537,23 @@ _glcpp_parser_expand_node (glcpp_parser_t *parser,
identifier = token->value.str;
macro = hash_table_find (parser->defines, identifier);
- /* Not a macro, so no expansion needed. */
- if (macro == NULL)
- return NULL;
+ /* Not a macro, so check the undefined-macro mode and
+ * conditionally convert the undefined macro to a zero-valued
+ * integer token. */
+ if (macro == NULL) {
+ token_list_t *replacement;
+ token_t *zero;
+
+ if (undefined_macro_mode == UNDEFINED_MACRO_IS_IDENTIFIER)
+ return NULL;
+
+ /* Return a zero in the place of this undefined macro. */
+ replacement = _token_list_create (parser);
+ zero = _token_create_ival (parser, INTEGER, 0);
+ _token_list_append (replacement, zero);
+ *last = node;
+ return replacement;
+ }
/* Finally, don't expand this macro if we're already actively
* expanding it, (to avoid infinite recursion). */
@@ -1620,7 +1650,8 @@ _parser_active_list_contains (glcpp_parser_t *parser, const char *identifier)
*/
static void
_glcpp_parser_expand_token_list (glcpp_parser_t *parser,
- token_list_t *list)
+ token_list_t *list,
+ undefined_macro_mode_t undefined_macro_mode)
{
token_node_t *node_prev;
token_node_t *node, *last = NULL;
@@ -1640,7 +1671,8 @@ _glcpp_parser_expand_token_list (glcpp_parser_t *parser,
while (parser->active && parser->active->marker == node)
_parser_active_list_pop (parser);
- expansion = _glcpp_parser_expand_node (parser, node, &last);
+ expansion = _glcpp_parser_expand_node (parser, node, &last,
+ undefined_macro_mode);
if (expansion) {
token_node_t *n;
@@ -1696,7 +1728,8 @@ _glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser,
if (list == NULL)
return;
- _glcpp_parser_expand_token_list (parser, list);
+ _glcpp_parser_expand_token_list (parser, list,
+ UNDEFINED_MACRO_IS_IDENTIFIER);
_token_list_trim_trailing_space (list);
--
1.7.10
More information about the mesa-dev
mailing list