Mesa (master): glcpp: Implement token pasting for non-function-like macros

Carl Worth cworth at kemper.freedesktop.org
Fri Sep 30 18:44:34 UTC 2011


Module: Mesa
Branch: master
Commit: 28842c2331e6df2cbe18c0be3487ece93680075d
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=28842c2331e6df2cbe18c0be3487ece93680075d

Author: Carl Worth <cworth at cworth.org>
Date:   Thu Sep 29 17:04:47 2011 -0700

glcpp: Implement token pasting for non-function-like macros

This is as simple as abstracting one existing block of code into a
function call and then adding a single call to that function for the
case of a non-function-like macro.

This fixes the recently-added 097-paste-with-non-function-macro test
as well as the following piglit tests:

	spec/glsl-1.30/preprocessor/concat/concat-01.frag
	spec/glsl-1.30/preprocessor/concat/concat-02.frag

Also, the concat-04.frag test now passes for the right reason. The
test is intended to fail the compilation, but before this commit it
was failing compilation (and hence passing the test) for the wrong
reason.

Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
Signed-off-by: Carl Worth <cworth at cworth.org>

---

 src/glsl/glcpp/glcpp-parse.y |   83 ++++++++++++++++++++++++------------------
 1 files changed, 47 insertions(+), 36 deletions(-)

diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y
index d547ecf..ff9fa7a 100644
--- a/src/glsl/glcpp/glcpp-parse.y
+++ b/src/glsl/glcpp/glcpp-parse.y
@@ -1275,6 +1275,48 @@ _glcpp_parser_expand_if (glcpp_parser_t *parser, int type, token_list_t *list)
 	glcpp_parser_lex_from (parser, expanded);
 }
 
+static void
+_glcpp_parser_apply_pastes (glcpp_parser_t *parser, token_list_t *list)
+{
+	token_node_t *node;
+
+	node = list->head;
+	while (node)
+	{
+		token_node_t *next_non_space;
+
+		/* Look ahead for a PASTE token, skipping space. */
+		next_non_space = node->next;
+		while (next_non_space && next_non_space->token->type == SPACE)
+			next_non_space = next_non_space->next;
+
+		if (next_non_space == NULL)
+			break;
+
+		if (next_non_space->token->type != PASTE) {
+			node = next_non_space;
+			continue;
+		}
+
+		/* Now find the next non-space token after the PASTE. */
+		next_non_space = next_non_space->next;
+		while (next_non_space && next_non_space->token->type == SPACE)
+			next_non_space = next_non_space->next;
+
+		if (next_non_space == NULL) {
+			yyerror (&node->token->location, parser, "'##' cannot appear at either end of a macro expansion\n");
+			return;
+		}
+
+		node->token = _token_paste (parser, node->token, next_non_space->token);
+		node->next = next_non_space->next;
+		if (next_non_space == list->tail)
+			list->tail = node;
+	}
+
+	list->non_space_tail = list->tail;
+}
+
 /* This is a helper function that's essentially part of the
  * implementation of _glcpp_parser_expand_node. It shouldn't be called
  * except for by that function.
@@ -1386,41 +1428,7 @@ _glcpp_parser_expand_function (glcpp_parser_t *parser,
 
 	_token_list_trim_trailing_space (substituted);
 
-	node = substituted->head;
-	while (node)
-	{
-		token_node_t *next_non_space;
-
-		/* Look ahead for a PASTE token, skipping space. */
-		next_non_space = node->next;
-		while (next_non_space && next_non_space->token->type == SPACE)
-			next_non_space = next_non_space->next;
-
-		if (next_non_space == NULL)
-			break;
-
-		if (next_non_space->token->type != PASTE) {
-			node = next_non_space;
-			continue;
-		}
-
-		/* Now find the next non-space token after the PASTE. */
-		next_non_space = next_non_space->next;
-		while (next_non_space && next_non_space->token->type == SPACE)
-			next_non_space = next_non_space->next;
-
-		if (next_non_space == NULL) {
-			yyerror (&node->token->location, parser, "'##' cannot appear at either end of a macro expansion\n");
-			return NULL;
-		}
-
-		node->token = _token_paste (parser, node->token, next_non_space->token);
-		node->next = next_non_space->next;
-		if (next_non_space == substituted->tail)
-			substituted->tail = node;
-	}
-
-	substituted->non_space_tail = substituted->tail;
+	_glcpp_parser_apply_pastes (parser, substituted);
 
 	return substituted;
 }
@@ -1490,13 +1498,16 @@ _glcpp_parser_expand_node (glcpp_parser_t *parser,
 
 	if (! macro->is_function)
 	{
+		token_list_t *replacement;
 		*last = node;
 
 		/* Replace a macro defined as empty with a SPACE token. */
 		if (macro->replacements == NULL)
 			return _token_list_create_with_one_space (parser);
 
-		return _token_list_copy (parser, macro->replacements);
+		replacement = _token_list_copy (parser, macro->replacements);
+		_glcpp_parser_apply_pastes (parser, replacement);
+		return replacement;
 	}
 
 	return _glcpp_parser_expand_function (parser, node, last);




More information about the mesa-commit mailing list