summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarl Worth <[email protected]>2012-06-09 16:31:06 -0700
committerCarl Worth <[email protected]>2012-06-26 15:23:49 -0700
commitaac78ce8234d96932c38b3f48b1d828077bc0027 (patch)
treea4e067870c6e57d69aeb68f8ea6717adf4cdee78
parent39f8c46eaa4d1c3b072cd97d256fe973c1791b14 (diff)
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 <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r--src/glsl/glcpp/glcpp-lex.l49
-rw-r--r--src/glsl/glcpp/glcpp-parse.y33
-rw-r--r--src/glsl/glcpp/glcpp.h5
-rw-r--r--src/glsl/glcpp/tests/091-hash-line.c.expected8
4 files changed, 55 insertions, 40 deletions
diff --git a/src/glsl/glcpp/glcpp-lex.l b/src/glsl/glcpp/glcpp-lex.l
index b34f2c0e9ad..7ab58cb288d 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 ee0018016d7..cc4af168976 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 2d7cad2e601..a13ade69ee4 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 e663398c160..ea29149bc62 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