[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