Mesa (master): glsl: glcpp: Move handling of #line directives from lexer to parser.

Carl Worth cworth at kemper.freedesktop.org
Tue Jun 26 22:37:26 UTC 2012


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

Author: Carl Worth <cworth at cworth.org>
Date:   Sat Jun  9 16:31:06 2012 -0700

glsl: glcpp: Move handling of #line directives from lexer to parser.

The GLSL specification requires that #line directives be interpreted
after macro expansion. Our existing implementation of #line macros in
the lexer prevents conformance on this point.

Moving the handling of #line from the lexer to the parser gives us the
macro expansion we need. An additional benefit is that the
preprocessor also now supports comments on the same line as #line
directives.

Finally, the preprocessor now emits the (fully-macro-expanded) #line
directives into the output. This allows the full GLSL compiler to also
see and interpret these directives so it can also generate correct
line numbers in error messages.

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

---

 src/glsl/glcpp/glcpp-lex.l                    |   49 +++++++------------------
 src/glsl/glcpp/glcpp-parse.y                  |   33 ++++++++++++++++-
 src/glsl/glcpp/glcpp.h                        |    5 +++
 src/glsl/glcpp/tests/091-hash-line.c.expected |    8 ++--
 4 files changed, 55 insertions(+), 40 deletions(-)

diff --git a/src/glsl/glcpp/glcpp-lex.l b/src/glsl/glcpp/glcpp-lex.l
index b34f2c0..7ab58cb 100644
--- a/src/glsl/glcpp/glcpp-lex.l
+++ b/src/glsl/glcpp/glcpp-lex.l
@@ -40,12 +40,18 @@ void glcpp_set_column (int  column_no , yyscan_t yyscanner);
 
 #define YY_NO_INPUT
 
-#define YY_USER_ACTION                                          \
-   do {                                                         \
-      yylloc->first_column = yycolumn + 1;                      \
-      yylloc->first_line = yylineno;                            \
-      yycolumn += yyleng;                                       \
-   } while(0);
+#define YY_USER_ACTION							\
+	do {								\
+		if (parser->has_new_line_number)			\
+			yylineno = parser->new_line_number;		\
+		if (parser->has_new_source_number)			\
+			yylloc->source = parser->new_source_number;	\
+		yylloc->first_column = yycolumn + 1;			\
+		yylloc->first_line = yylineno;				\
+		yycolumn += yyleng;					\
+		parser->has_new_line_number = 0;			\
+		parser->has_new_source_number = 0;			\
+ } while(0);
 
 #define YY_USER_INIT			\
 	do {				\
@@ -129,35 +135,8 @@ HEXADECIMAL_INTEGER	0[xX][0-9a-fA-F]+[uU]?
 	return OTHER;
 }
 
-{HASH}line{HSPACE}+{DIGITS}{HSPACE}+{DIGITS}{HSPACE}*$ {
-	/* Eat characters until the first digit is
-	 * encountered
-	 */
-	char *ptr = yytext;
-	while (!isdigit(*ptr))
-		ptr++;
-
-	/* Subtract one from the line number because
-	 * yylineno is zero-based instead of
-	 * one-based.
-	 */
-	yylineno = strtol(ptr, &ptr, 0) - 1;
-	yylloc->source = strtol(ptr, NULL, 0);
-}
-
-{HASH}line{HSPACE}+{DIGITS}{HSPACE}*$ {
-	/* Eat characters until the first digit is
-	 * encountered
-	 */
-	char *ptr = yytext;
-	while (!isdigit(*ptr))
-		ptr++;
-
-	/* Subtract one from the line number because
-	 * yylineno is zero-based instead of
-	 * one-based.
-	 */
-	yylineno = strtol(ptr, &ptr, 0) - 1;
+{HASH}line {
+	return HASH_LINE;
 }
 
 <SKIP,INITIAL>{
diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y
index ee00180..cc4af16 100644
--- a/src/glsl/glcpp/glcpp-parse.y
+++ b/src/glsl/glcpp/glcpp-parse.y
@@ -162,7 +162,7 @@ add_builtin_define(glcpp_parser_t *parser, const char *name, int value);
 %lex-param {glcpp_parser_t *parser}
 
 %expect 0
-%token COMMA_FINAL DEFINED ELIF_EXPANDED HASH HASH_DEFINE_FUNC HASH_DEFINE_OBJ HASH_ELIF HASH_ELSE HASH_ENDIF HASH_IF HASH_IFDEF HASH_IFNDEF HASH_UNDEF HASH_VERSION IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING NEWLINE OTHER PLACEHOLDER SPACE
+%token COMMA_FINAL DEFINED ELIF_EXPANDED HASH HASH_DEFINE_FUNC HASH_DEFINE_OBJ HASH_ELIF HASH_ELSE HASH_ENDIF HASH_IF HASH_IFDEF HASH_IFNDEF HASH_LINE HASH_UNDEF HASH_VERSION IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE
 %token PASTE
 %type <ival> expression INTEGER operator SPACE integer_constant
 %type <str> IDENTIFIER INTEGER_STRING OTHER
@@ -208,6 +208,24 @@ expanded_line:
 |	ELIF_EXPANDED expression NEWLINE {
 		_glcpp_parser_skip_stack_change_if (parser, & @1, "elif", $2);
 	}
+|	LINE_EXPANDED integer_constant NEWLINE {
+		parser->has_new_line_number = 1;
+		parser->new_line_number = $2;
+		ralloc_asprintf_rewrite_tail (&parser->output,
+					      &parser->output_length,
+					      "#line %" PRIiMAX,
+					      $2);
+	}
+|	LINE_EXPANDED integer_constant integer_constant NEWLINE {
+		parser->has_new_line_number = 1;
+		parser->new_line_number = $2;
+		parser->has_new_source_number = 1;
+		parser->new_source_number = $3;
+		ralloc_asprintf_rewrite_tail (&parser->output,
+					      &parser->output_length,
+					      "#line %" PRIiMAX " %" PRIiMAX,
+					      $2, $3);
+	}
 ;
 
 control_line:
@@ -228,6 +246,14 @@ control_line:
 		}
 		ralloc_free ($2);
 	}
+|	HASH_LINE pp_tokens NEWLINE {
+		if (parser->skip_stack == NULL ||
+		    parser->skip_stack->type == SKIP_NO_SKIP)
+		{
+			_glcpp_parser_expand_and_lex_from (parser,
+							   LINE_EXPANDED, $2);
+		}
+	}
 |	HASH_IF conditional_tokens NEWLINE {
 		/* Be careful to only evaluate the 'if' expression if
 		 * we are not skipping. When we are skipping, we
@@ -1120,6 +1146,11 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api)
 	parser->info_log_length = 0;
 	parser->error = 0;
 
+	parser->has_new_line_number = 0;
+	parser->new_line_number = 1;
+	parser->has_new_source_number = 0;
+	parser->new_source_number = 0;
+
 	/* Add pre-defined macros. */
 	add_builtin_define(parser, "GL_ARB_draw_buffers", 1);
 	add_builtin_define(parser, "GL_ARB_texture_rectangle", 1);
diff --git a/src/glsl/glcpp/glcpp.h b/src/glsl/glcpp/glcpp.h
index 2d7cad2..a13ade6 100644
--- a/src/glsl/glcpp/glcpp.h
+++ b/src/glsl/glcpp/glcpp.h
@@ -25,6 +25,7 @@
 #define GLCPP_H
 
 #include <stdint.h>
+#include <stdbool.h>
 
 #include "../ralloc.h"
 
@@ -177,6 +178,10 @@ struct glcpp_parser {
 	size_t output_length;
 	size_t info_log_length;
 	int error;
+	bool has_new_line_number;
+	int new_line_number;
+	bool has_new_source_number;
+	int new_source_number;
 };
 
 struct gl_extensions;
diff --git a/src/glsl/glcpp/tests/091-hash-line.c.expected b/src/glsl/glcpp/tests/091-hash-line.c.expected
index e663398..ea29149 100644
--- a/src/glsl/glcpp/tests/091-hash-line.c.expected
+++ b/src/glsl/glcpp/tests/091-hash-line.c.expected
@@ -3,11 +3,11 @@
 1:0(1): preprocessor error: #error source 1, line 0 error
 2:30(1): preprocessor error: #error source 2, line 30 error
 
+#line 0
 
+#line 25
 
+#line 0 1
 
-
-
-
-
+#line 30 2
 




More information about the mesa-commit mailing list