No hookup with GL yet. Planned to be used to simplify profiles. Signed-off-by: Olivier Galibert <galib...@pobox.com> --- src/glsl/ast.h | 12 ++- src/glsl/glcpp/glcpp-lex.l | 135 ++++++++++++++++++++++++-- src/glsl/glcpp/glcpp-parse.y | 75 +++++++++++++- src/glsl/glcpp/glcpp.c | 14 +++- src/glsl/glcpp/glcpp.h | 56 ++++++++++- src/glsl/glcpp/pp.c | 92 ++++++++++++++++- src/glsl/glsl_lexer.ll | 32 ++++++- src/glsl/glsl_parser.yy | 203 ++++++++++++++++++++------------------- src/glsl/glsl_parser_extras.cpp | 23 ++++- src/glsl/glsl_parser_extras.h | 16 +++- src/glsl/main.cpp | 24 ++++- src/glsl/test_optpass.cpp | 2 +- src/mesa/program/ir_to_mesa.cpp | 2 +- 13 files changed, 542 insertions(+), 144 deletions(-)
diff --git a/src/glsl/ast.h b/src/glsl/ast.h index 1f78af8..b0bfb28 100644 --- a/src/glsl/ast.h +++ b/src/glsl/ast.h @@ -65,6 +65,9 @@ public: * ralloc_free in that case. */ static void operator delete(void *table) { + ast_node *an = static_cast<ast_node *>(table); + if(an->location.source) + ralloc_free(an->location.source); ralloc_free(table); } @@ -92,6 +95,7 @@ public: struct YYLTYPE locp; locp.source = this->location.source; + locp.source_id = this->location.source_id; locp.first_line = this->location.line; locp.first_column = this->location.column; locp.last_line = locp.first_line; @@ -105,9 +109,10 @@ public: * * \sa ast_node::get_location */ - void set_location(const struct YYLTYPE &locp) + void set_location(const struct YYLTYPE &locp, void *ctx) { - this->location.source = locp.source; + this->location.source = locp.source ? ralloc_strdup(ctx, locp.source) : 0; + this->location.source_id = locp.source_id; this->location.line = locp.first_line; this->location.column = locp.first_column; } @@ -116,7 +121,8 @@ public: * Source location of the AST node. */ struct { - unsigned source; /**< GLSL source number. */ + unsigned source_id; /**< GLSL source number (if source is NULL) */ + char *source; /**< GLSL source file or NULL */ unsigned line; /**< Line number within the source string. */ unsigned column; /**< Column in the line. */ } location; diff --git a/src/glsl/glcpp/glcpp-lex.l b/src/glsl/glcpp/glcpp-lex.l index b34f2c0..2ce1547 100644 --- a/src/glsl/glcpp/glcpp-lex.l +++ b/src/glsl/glcpp/glcpp-lex.l @@ -44,6 +44,8 @@ void glcpp_set_column (int column_no , yyscan_t yyscanner); do { \ yylloc->first_column = yycolumn + 1; \ yylloc->first_line = yylineno; \ + yylloc->source = yyextra->source; \ + yylloc->source_id = yyextra->source_id; \ yycolumn += yyleng; \ } while(0); @@ -51,17 +53,16 @@ void glcpp_set_column (int column_no , yyscan_t yyscanner); do { \ yylineno = 1; \ yycolumn = 1; \ - yylloc->source = 0; \ } while(0) %} -%option bison-bridge bison-locations reentrant noyywrap +%option bison-bridge bison-locations reentrant %option extra-type="glcpp_parser_t *" %option prefix="glcpp_" %option stack %option never-interactive -%x DONE COMMENT UNREACHABLE SKIP +%x DONE COMMENT UNREACHABLE SKIP EXTENSION SPACE [[:space:]] NONSPACE [^[:space:]] @@ -69,7 +70,8 @@ NEWLINE [\n] HSPACE [ \t] HASH ^{HSPACE}*#{HSPACE}* IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]* -PUNCTUATION [][(){}.&*~!/%<>^|;,=+-] +PUNCTUATION [][(){}.&*~!/%<>^|;,=+-:] +STRING "\""[^"\n]+"\"" /* The OTHER class is simply a catch-all for things that the CPP parser just doesn't care about. Since flex regular expressions that @@ -78,7 +80,7 @@ strings, we have to be careful to avoid OTHER matching and hiding something that CPP does care about. So we simply exclude all characters that appear in any other expressions. */ -OTHER [^][_#[:space:]#a-zA-Z0-9(){}.&*~!/%<>^|;,=+-] +OTHER [^][_#[:space:]#a-zA-Z0-9(){}.&*~!/%<>^|;,=+-:] DIGITS [0-9][0-9]* DECIMAL_INTEGER [1-9][0-9]*[uU]? @@ -120,15 +122,45 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? return HASH_VERSION; } - /* glcpp doesn't handle #extension, #version, or #pragma directives. +{HASH}extension{HSPACE}+ { + return HASH_EXTENSION; +} + + /* glcpp doesn't handle #pragma directives. * Simply pass them through to the main compiler's lexer/parser. */ -{HASH}(extension|pragma)[^\n]+ { +{HASH}pragma[^\n]+ { yylval->str = ralloc_strdup (yyextra, yytext); yylineno++; yycolumn = 0; return OTHER; } +{HASH}include{HSPACE}*{STRING}{HSPACE}*$ { + char *ptr = yytext; + while (*ptr != '"') + ptr++; + ptr++; + char *eptr = ptr; + while (*eptr != '"') + eptr++; + *eptr = 0; + yylval->str = ralloc_strdup (yyextra, ptr); + return HASH_INCLUDE; +} + +{HASH}include{HSPACE}*<[^>\n]>+{HSPACE}*$ { + char *ptr = yytext; + while (*ptr != '<') + ptr++; + ptr++; + char *eptr = ptr; + while (*eptr != '>') + eptr++; + *eptr = 0; + yylval->str = ralloc_strdup (yyextra, ptr); + return HASH_INCLUDE; +} + {HASH}line{HSPACE}+{DIGITS}{HSPACE}+{DIGITS}{HSPACE}*$ { /* Eat characters until the first digit is * encountered @@ -142,7 +174,33 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? * one-based. */ yylineno = strtol(ptr, &ptr, 0) - 1; - yylloc->source = strtol(ptr, NULL, 0); + yyextra->source_id = yylloc->source_id = strtol(ptr, NULL, 0); + yyextra->source = yylloc->source = 0; +} + +{HASH}line{HSPACE}+{DIGITS}{HSPACE}+{STRING}{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; + + while (*ptr != '"') + ptr++; + ptr++; + char *eptr = ptr; + while (*eptr != '"') + eptr++; + *eptr = 0; + yyextra->source_id = yylloc->source_id = 0; + yyextra->source = yylloc->source = ralloc_strdup(yyextra, ptr); } {HASH}line{HSPACE}+{DIGITS}{HSPACE}*$ { @@ -328,5 +386,64 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? void glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader) { - yy_scan_string(shader, parser->scanner); + parser->current_buffer = yy_scan_string(shader, parser->scanner); + glcpp_set_lineno (1, parser->scanner); +} + + +void +glcpp_push_input (glcpp_parser_t *parser, const char *data, const char *base_path, const char *file_name) +{ + struct glcpp_parser_input_file *is = ralloc (parser, struct glcpp_parser_input_file); + is->base_path = parser->base_path; + is->buffer = parser->current_buffer; + is->prev = parser->input_stack; + + is->source = parser->source; + is->source_id = parser->source_id; + + parser->input_stack = is; + + parser->base_path = base_path; + glcpp_lex_set_source_string(parser, data); + + parser->source = file_name; + parser->source_id = 0; +} + +int +glcpp_wrap (yyscan_t scanner) +{ + glcpp_parser_t *parser = glcpp_get_extra (scanner); + if (glcpp_input_stack_empty (parser)) + return 1; + glcpp_pop_input (parser); + return 0; +} + +int +glcpp_input_stack_empty (glcpp_parser_t *parser) +{ + return !parser->input_stack; +} + +void +glcpp_pop_input (glcpp_parser_t *parser) +{ + struct glcpp_parser_input_file *is = parser->input_stack; + parser->input_stack = is->prev; + parser->base_path = is->base_path; + yy_delete_buffer(parser->current_buffer, parser->scanner); + parser->current_buffer = is->buffer; + yy_switch_to_buffer (parser->current_buffer, parser->scanner); + + parser->source = is->source; + parser->source_id = is->source_id; + + if (parser->source) + ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "#line %d \"%s\"\n", glcpp_get_lineno (parser->scanner)-1, parser->source); + else + ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "#line %d %d\n", glcpp_get_lineno (parser->scanner)-1, parser->source_id); + + ralloc_free (is); } diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y index 47ba54d..ec94290 100644 --- a/src/glsl/glcpp/glcpp-parse.y +++ b/src/glsl/glcpp/glcpp-parse.y @@ -150,16 +150,17 @@ add_builtin_define(glcpp_parser_t *parser, const char *name, int value); @$.last_line = 1; @$.last_column = 1; @$.source = 0; + @$.source_id = 0; } %parse-param {glcpp_parser_t *parser} %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 PASTE +%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 HASH_INCLUDE HASH_EXTENSION IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING NEWLINE OTHER PLACEHOLDER SPACE +%token PASTE ':' %type <ival> expression INTEGER operator SPACE integer_constant -%type <str> IDENTIFIER INTEGER_STRING OTHER +%type <str> IDENTIFIER INTEGER_STRING OTHER HASH_INCLUDE %type <string_list> identifier_list %type <token> preprocessing_token conditional_token %type <token_list> pp_tokens replacement_list text_line conditional_tokens @@ -193,6 +194,8 @@ line: } | expanded_line | HASH non_directive +| extension_line +| include_line ; expanded_line: @@ -325,6 +328,59 @@ control_line: | HASH NEWLINE ; +extension_line: + HASH_EXTENSION IDENTIFIER space_or_nothing ':' space_or_nothing IDENTIFIER space_or_nothing NEWLINE { + if (!strcmp ($2, "GL_ARB_shading_language_include")) { + if (!strcmp ($6, "enable") || !strcmp($6, "require")) + parser->include_mode = INCLUDE_OK; + else if (!strcmp ($6, "disable")) + parser->include_mode = INCLUDE_DISABLED; + else if (!strcmp ($6, "warn")) + parser->include_mode = INCLUDE_WARN; + else + yyerror (& @6, parser, "Unknown extension behavior"); + } + else + { + if (!strcmp ($2, "all")) { + if (!strcmp ($6, "warn")) + parser->include_mode = INCLUDE_WARN; + else if (!strcmp ($6, "disable")) + parser->include_mode = INCLUDE_DISABLED; + } + ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "#extension %s : %s\n", $2, $6); + ralloc_free ($2); + ralloc_free ($6); + } + } +; + +include_line: + HASH_INCLUDE { + if (parser->include_mode == INCLUDE_DISABLED) + glcpp_error (&@1, parser, "#include encountered with GL_ARB_shading_language_include disabled\n"); + else + { + if (parser->include_mode == INCLUDE_WARN) + glcpp_error (&@1, parser, "#include encountered with GL_ARB_shading_language_include set to warn\n"); + char *new_base_path = glcpp_canonicalize_path (parser, parser->base_path, $1); + char *new_file_name = glcpp_add_file_name (parser, new_base_path, $1); + const char *subshader = parser->include_get_string (parser->include_param, new_file_name); + if (!subshader) + glcpp_error (&@1, parser, "Could not find string for inclusion: %s\n", new_file_name); + else { + ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "#line 1 \"%s\"\n", new_file_name); + glcpp_push_input (parser, subshader, new_base_path, new_file_name); + } + } + } +; + +space_or_nothing: + SPACE +| /* empty */ +; + integer_constant: INTEGER_STRING { if (strlen ($1) >= 3 && strncmp ($1, "0x", 2) == 0) { @@ -551,7 +607,6 @@ operator: | '=' { $$ = '='; } | PASTE { $$ = PASTE; } ; - %% string_list_t * @@ -1081,7 +1136,9 @@ static void add_builtin_define(glcpp_parser_t *parser, } glcpp_parser_t * -glcpp_parser_create (const struct gl_extensions *extensions, int api) +glcpp_parser_create (const struct gl_extensions *extensions, int api, + const char *base_path, + const char *(*get_string)(void *param, const char *), void *param) { glcpp_parser_t *parser; int language_version; @@ -1097,6 +1154,13 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api) parser->newline_as_space = 0; parser->in_control_line = 0; parser->paren_count = 0; + parser->include_mode = INCLUDE_DISABLED; + parser->base_path = base_path; + parser->include_get_string = get_string; + parser->include_param = param; + parser->input_stack = NULL; + parser->source = 0; + parser->source_id = 0; parser->skip_stack = NULL; @@ -1763,7 +1827,6 @@ glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser) if (parser->lex_from_list == NULL) { ret = glcpp_lex (yylval, yylloc, parser->scanner); - /* XXX: This ugly block of code exists for the sole * purpose of converting a NEWLINE token into a SPACE * token, but only in the case where we have seen a diff --git a/src/glsl/glcpp/glcpp.c b/src/glsl/glcpp/glcpp.c index e461a65..8fce570 100644 --- a/src/glsl/glcpp/glcpp.c +++ b/src/glsl/glcpp/glcpp.c @@ -24,6 +24,7 @@ #include <stdio.h> #include <string.h> #include <errno.h> +#include <unistd.h> #include "glcpp.h" #include "main/mtypes.h" #include "main/shaderobj.h" @@ -94,6 +95,12 @@ load_text_file(void *ctx, const char *filename) return text; } +static const char * +get_string (void *ctx, const char *name) +{ + return load_text_file(ctx, name); +} + int main (int argc, char *argv[]) { @@ -107,11 +114,16 @@ main (int argc, char *argv[]) filename = argv[1]; } + char *cur_dir = get_current_dir_name(); + char *base_path = glcpp_canonicalize_path(NULL, cur_dir, filename ? filename : ""); + free(cur_dir); + shader = load_text_file (ctx, filename); if (shader == NULL) return 1; - ret = preprocess(ctx, &shader, &info_log, NULL, API_OPENGL); + ret = preprocess(ctx, &shader, &info_log, NULL, API_OPENGL, base_path, get_string, ctx); + ralloc_free(base_path); printf("%s", shader); fprintf(stderr, "%s", info_log); diff --git a/src/glsl/glcpp/glcpp.h b/src/glsl/glcpp/glcpp.h index 2d7cad2..ebcd90b 100644 --- a/src/glsl/glcpp/glcpp.h +++ b/src/glsl/glcpp/glcpp.h @@ -64,10 +64,11 @@ typedef struct YYLTYPE { int first_column; int last_line; int last_column; - unsigned source; + const char *source; + unsigned source_id; } YYLTYPE; # define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 +# undef YYLTYPE_IS_TRIVIAL # define YYLLOC_DEFAULT(Current, Rhs, N) \ do { \ @@ -77,6 +78,8 @@ do { \ (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ (Current).last_column = YYRHSLOC(Rhs, N).last_column; \ + (Current).source = YYRHSLOC(Rhs, 1).source; \ + (Current).source_id = YYRHSLOC(Rhs, 1).source_id; \ } \ else \ { \ @@ -84,6 +87,8 @@ do { \ YYRHSLOC(Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC(Rhs, 0).last_column; \ + (Current).source = YYRHSLOC(Rhs, 0).source; \ + (Current).source_id = YYRHSLOC(Rhs, 0).source_id; \ } \ (Current).source = 0; \ } while (0) @@ -160,6 +165,20 @@ typedef struct active_list { struct active_list *next; } active_list_t; +typedef enum { + INCLUDE_DISABLED, + INCLUDE_WARN, + INCLUDE_OK +} include_mode_t; + +struct glcpp_parser_input_file { + struct glcpp_parser_input_file *prev; + struct yy_buffer_state *buffer; + const char *base_path; + const char *source; + unsigned source_id; +}; + struct glcpp_parser { yyscan_t scanner; struct hash_table *defines; @@ -169,6 +188,7 @@ struct glcpp_parser { int newline_as_space; int in_control_line; int paren_count; + include_mode_t include_mode; skip_node_t *skip_stack; token_list_t *lex_from_list; token_node_t *lex_from_node; @@ -177,12 +197,21 @@ struct glcpp_parser { size_t output_length; size_t info_log_length; int error; + unsigned int source_id; + const char *base_path; + const char *source; + const char *(*include_get_string)(void *param, const char *); + void *include_param; + struct yy_buffer_state *current_buffer; + struct glcpp_parser_input_file *input_stack; }; struct gl_extensions; glcpp_parser_t * -glcpp_parser_create (const struct gl_extensions *extensions, int api); +glcpp_parser_create (const struct gl_extensions *extensions, int api, + const char *base_path, + const char *(*get_string)(void *param, const char *), void *param); int glcpp_parser_parse (glcpp_parser_t *parser); @@ -192,7 +221,9 @@ glcpp_parser_destroy (glcpp_parser_t *parser); int preprocess(void *ralloc_ctx, const char **shader, char **info_log, - const struct gl_extensions *extensions, int api); + const struct gl_extensions *extensions, int api, + const char *base_path, + const char *(*get_string)(void *param, const char *), void *param); /* Functions for writing to the info log */ @@ -202,6 +233,23 @@ glcpp_error (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...); void glcpp_warning (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...); +/* Functions for include support */ + +char * +glcpp_canonicalize_path (void *ctx, const char *base_path, const char *file_name); + +char * +glcpp_add_file_name (void *ctx, const char *base_path, const char *file_name); + +void +glcpp_push_input (glcpp_parser_t *parser, const char *data, const char *base_path, const char *file_name); + +int +glcpp_input_stack_empty (glcpp_parser_t *parser); + +void +glcpp_pop_input (glcpp_parser_t *parser); + /* Generated by glcpp-lex.l to glcpp-lex.c */ int diff --git a/src/glsl/glcpp/pp.c b/src/glsl/glcpp/pp.c index 3640896..10c239c 100644 --- a/src/glsl/glcpp/pp.c +++ b/src/glsl/glcpp/pp.c @@ -32,10 +32,17 @@ glcpp_error (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...) { va_list ap; + char sbuf[12]; + const char *source = locp->source; + if (!source) { + source = sbuf; + sprintf (sbuf, "%u", locp->source_id); + } + parser->error = 1; - ralloc_asprintf_append(&parser->info_log, "%u:%u(%u): " + ralloc_asprintf_append(&parser->info_log, "%s:%u(%u): " "preprocessor error: ", - locp->source, + source, locp->first_line, locp->first_column); va_start(ap, fmt); @@ -49,9 +56,15 @@ glcpp_warning (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...) { va_list ap; - ralloc_asprintf_append(&parser->info_log, "%u:%u(%u): " + char sbuf[12]; + const char *source = locp->source; + if (!source) { + source = sbuf; + sprintf (sbuf, "%u", locp->source_id); + } + ralloc_asprintf_append(&parser->info_log, "%s:%u(%u): " "preprocessor warning: ", - locp->source, + source, locp->first_line, locp->first_column); va_start(ap, fmt); @@ -60,6 +73,71 @@ glcpp_warning (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...) ralloc_strcat(&parser->info_log, "\n"); } +char * +glcpp_canonicalize_path(void *ctx, const char *base_path, const char *file_name) +{ + if(file_name[0] == '/') + base_path = ""; + + char *res = ralloc_size(ctx, strlen(base_path) + strlen(file_name) + 2); + sprintf(res, "%s/%s", base_path, file_name); + + // Cleanup //, . and .. and final file name + + // base_path, and hence the buffer, will always start with '/' + + // rp is the current read position, prp is the position of the + // first character after the previous '/', wp is the (re)write + // position + + const char *rp = res+1; + const char *prp = res+1; + char *wp = res; + while(*rp) { + if(*rp == '/') { + // Eliminate successions of '/' + if(rp == prp) { + } + // Drop '.' + else if(rp == prp+1 && prp[0] == '.') { + } + // Rewind one level on '..', don't go past the beginning of buffer + else if(rp == prp+2 && prp[0] == '.' && prp[1] == '.') { + while(wp != res && wp[-1] != '/') + wp--; + } + // Copy path element + else + { + *wp++ = '/'; + while(prp != rp) + *wp++ = *prp++; + } + rp++; + prp = rp; + } + else + rp++; + } + *wp = 0; + + return res; +} + +char * +glcpp_add_file_name(void *ctx, const char *base_path, const char *file_name) +{ + const char *slash_pos = strrchr(file_name, '/'); + if(slash_pos) + slash_pos++; + else + slash_pos = file_name; + + char *res = ralloc_size(ctx, strlen(base_path) + strlen(slash_pos) + 2); + sprintf(res, "%s/%s", base_path, slash_pos); + return res; +} + /* Searches backwards for '^ *#' from a given starting point. */ static int in_directive(const char *shader, const char *ptr) @@ -141,10 +219,12 @@ remove_line_continuations(glcpp_parser_t *ctx, const char *shader) int preprocess(void *ralloc_ctx, const char **shader, char **info_log, - const struct gl_extensions *extensions, int api) + const struct gl_extensions *extensions, int api, + const char *base_path, + const char *(*get_string)(void *param, const char *), void *param) { int errors; - glcpp_parser_t *parser = glcpp_parser_create (extensions, api); + glcpp_parser_t *parser = glcpp_parser_create (extensions, api, base_path, get_string, param); *shader = remove_line_continuations(parser, *shader); glcpp_lex_set_source_string (parser, *shader); diff --git a/src/glsl/glsl_lexer.ll b/src/glsl/glsl_lexer.ll index 936a907..b604ce6 100644 --- a/src/glsl/glsl_lexer.ll +++ b/src/glsl/glsl_lexer.ll @@ -36,7 +36,8 @@ static int classify_identifier(struct _mesa_glsl_parse_state *, const char *); #define YY_USER_ACTION \ do { \ - yylloc->source = 0; \ + yylloc->source = yyextra->source; \ + yylloc->source_id = yyextra->source_id; \ yylloc->first_column = yycolumn + 1; \ yylloc->first_line = yylineno + 1; \ yycolumn += yyleng; \ @@ -142,6 +143,7 @@ INT ({DEC_INT}|{HEX_INT}|{OCT_INT}) SPC [ \t]* SPCP [ \t]+ HASH ^{SPC}#{SPC} +STR "\""[^"\n]+"\"" %% [ \r\t]+ ; @@ -163,7 +165,33 @@ HASH ^{SPC}#{SPC} * one-based. */ yylineno = strtol(ptr, &ptr, 0) - 1; - yylloc->source = strtol(ptr, NULL, 0); + yyextra->source_id = yylloc->source_id = strtol(ptr, NULL, 0); + yyextra->source = yylloc->source = 0; + } +{HASH}line{SPCP}{INT}{SPCP}{STR}{SPC}$ { + /* Eat characters until the first digit is + * encountered + */ + char *ptr = yytext; + while (!isdigit(*ptr)) + ptr++; + + while (*ptr != '"') + ptr++; + ptr++; + char *eptr = ptr; + while (*eptr != '"') + eptr++; + *eptr = 0; + + yyextra->source_id = yylloc->source_id = 0; + yyextra->source = yylloc->source = strdup(ptr); +// must use ralloc_strdup + /* Subtract one from the line number because + * yylineno is zero-based instead of + * one-based. + */ + yylineno = strtol(ptr, &ptr, 0) - 1; } {HASH}line{SPCP}{INT}{SPC}$ { /* Eat characters until the first digit is diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy index 9a0af95..ac834eb 100644 --- a/src/glsl/glsl_parser.yy +++ b/src/glsl/glsl_parser.yy @@ -50,6 +50,7 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg) @$.last_line = 1; @$.last_column = 1; @$.source = 0; + @$.source_id = 0; } %lex-param {void *scanner} @@ -353,35 +354,35 @@ primary_expression: { void *ctx = state; $$ = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->primary_expression.identifier = $1; } | INTCONSTANT { void *ctx = state; $$ = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->primary_expression.int_constant = $1; } | UINTCONSTANT { void *ctx = state; $$ = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->primary_expression.uint_constant = $1; } | FLOATCONSTANT { void *ctx = state; $$ = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->primary_expression.float_constant = $1; } | BOOLCONSTANT { void *ctx = state; $$ = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->primary_expression.bool_constant = $1; } | '(' expression ')' @@ -396,7 +397,7 @@ postfix_expression: { void *ctx = state; $$ = new(ctx) ast_expression(ast_array_index, $1, $3, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | function_call { @@ -406,20 +407,20 @@ postfix_expression: { void *ctx = state; $$ = new(ctx) ast_expression(ast_field_selection, $1, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->primary_expression.identifier = $3; } | postfix_expression INC_OP { void *ctx = state; $$ = new(ctx) ast_expression(ast_post_inc, $1, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | postfix_expression DEC_OP { void *ctx = state; $$ = new(ctx) ast_expression(ast_post_dec, $1, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -437,7 +438,7 @@ function_call_or_method: { void *ctx = state; $$ = new(ctx) ast_expression(ast_field_selection, $1, $3, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -455,13 +456,13 @@ function_call_header_with_parameters: function_call_header assignment_expression { $$ = $1; - $$->set_location(yylloc); + $$->set_location(yylloc, state); $$->expressions.push_tail(& $2->link); } | function_call_header_with_parameters ',' assignment_expression { $$ = $1; - $$->set_location(yylloc); + $$->set_location(yylloc, state); $$->expressions.push_tail(& $3->link); } ; @@ -478,21 +479,21 @@ function_identifier: { void *ctx = state; $$ = new(ctx) ast_function_expression($1); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | variable_identifier { void *ctx = state; ast_expression *callee = new(ctx) ast_expression($1); $$ = new(ctx) ast_function_expression(callee); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | FIELD_SELECTION { void *ctx = state; ast_expression *callee = new(ctx) ast_expression($1); $$ = new(ctx) ast_function_expression(callee); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -510,13 +511,13 @@ method_call_header_with_parameters: method_call_header assignment_expression { $$ = $1; - $$->set_location(yylloc); + $$->set_location(yylloc, state); $$->expressions.push_tail(& $2->link); } | method_call_header_with_parameters ',' assignment_expression { $$ = $1; - $$->set_location(yylloc); + $$->set_location(yylloc, state); $$->expressions.push_tail(& $3->link); } ; @@ -530,7 +531,7 @@ method_call_header: void *ctx = state; ast_expression *callee = new(ctx) ast_expression($1); $$ = new(ctx) ast_function_expression(callee); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -541,19 +542,19 @@ unary_expression: { void *ctx = state; $$ = new(ctx) ast_expression(ast_pre_inc, $2, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | DEC_OP unary_expression { void *ctx = state; $$ = new(ctx) ast_expression(ast_pre_dec, $2, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | unary_operator unary_expression { void *ctx = state; $$ = new(ctx) ast_expression($1, $2, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -571,19 +572,19 @@ multiplicative_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_mul, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | multiplicative_expression '/' unary_expression { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_div, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | multiplicative_expression '%' unary_expression { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_mod, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -593,13 +594,13 @@ additive_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_add, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | additive_expression '-' multiplicative_expression { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_sub, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -609,13 +610,13 @@ shift_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_lshift, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | shift_expression RIGHT_OP additive_expression { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_rshift, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -625,25 +626,25 @@ relational_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_less, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | relational_expression '>' shift_expression { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_greater, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | relational_expression LE_OP shift_expression { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_lequal, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | relational_expression GE_OP shift_expression { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_gequal, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -653,13 +654,13 @@ equality_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_equal, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | equality_expression NE_OP relational_expression { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_nequal, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -669,7 +670,7 @@ and_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_bit_and, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -679,7 +680,7 @@ exclusive_or_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_bit_xor, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -689,7 +690,7 @@ inclusive_or_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -699,7 +700,7 @@ logical_and_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_logic_and, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -709,7 +710,7 @@ logical_xor_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_logic_xor, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -719,7 +720,7 @@ logical_or_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_logic_or, $1, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -729,7 +730,7 @@ conditional_expression: { void *ctx = state; $$ = new(ctx) ast_expression(ast_conditional, $1, $3, $5); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -739,7 +740,7 @@ assignment_expression: { void *ctx = state; $$ = new(ctx) ast_expression($2, $1, $3, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -767,7 +768,7 @@ expression: void *ctx = state; if ($1->oper != ast_sequence) { $$ = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->expressions.push_tail(& $1->link); } else { $$ = $1; @@ -826,7 +827,7 @@ function_header: { void *ctx = state; $$ = new(ctx) ast_function(); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->return_type = $1; $$->identifier = $2; @@ -840,9 +841,9 @@ parameter_declarator: { void *ctx = state; $$ = new(ctx) ast_parameter_declarator(); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->type = new(ctx) ast_fully_specified_type(); - $$->type->set_location(yylloc); + $$->type->set_location(yylloc, ctx); $$->type->specifier = $1; $$->identifier = $2; } @@ -850,9 +851,9 @@ parameter_declarator: { void *ctx = state; $$ = new(ctx) ast_parameter_declarator(); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->type = new(ctx) ast_fully_specified_type(); - $$->type->set_location(yylloc); + $$->type->set_location(yylloc, ctx); $$->type->specifier = $1; $$->identifier = $2; $$->is_array = true; @@ -879,7 +880,7 @@ parameter_declaration: $1.flags.i |= $2.flags.i; $$ = new(ctx) ast_parameter_declarator(); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->type = new(ctx) ast_fully_specified_type(); $$->type->qualifier = $1; $$->type->specifier = $3; @@ -888,7 +889,7 @@ parameter_declaration: { void *ctx = state; $$ = new(ctx) ast_parameter_declarator(); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->type = new(ctx) ast_fully_specified_type(); $$->type->qualifier = $1; $$->type->specifier = $2; @@ -928,7 +929,7 @@ init_declarator_list: { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, NULL); - decl->set_location(yylloc); + decl->set_location(yylloc, ctx); $$ = $1; $$->declarations.push_tail(&decl->link); @@ -938,7 +939,7 @@ init_declarator_list: { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, NULL); - decl->set_location(yylloc); + decl->set_location(yylloc, ctx); $$ = $1; $$->declarations.push_tail(&decl->link); @@ -948,7 +949,7 @@ init_declarator_list: { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, NULL); - decl->set_location(yylloc); + decl->set_location(yylloc, ctx); $$ = $1; $$->declarations.push_tail(&decl->link); @@ -958,7 +959,7 @@ init_declarator_list: { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, $7); - decl->set_location(yylloc); + decl->set_location(yylloc, ctx); $$ = $1; $$->declarations.push_tail(&decl->link); @@ -968,7 +969,7 @@ init_declarator_list: { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, $8); - decl->set_location(yylloc); + decl->set_location(yylloc, ctx); $$ = $1; $$->declarations.push_tail(&decl->link); @@ -978,7 +979,7 @@ init_declarator_list: { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, $5); - decl->set_location(yylloc); + decl->set_location(yylloc, ctx); $$ = $1; $$->declarations.push_tail(&decl->link); @@ -993,7 +994,7 @@ single_declaration: void *ctx = state; /* Empty declaration list is valid. */ $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | fully_specified_type any_identifier { @@ -1001,7 +1002,7 @@ single_declaration: ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL); $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->declarations.push_tail(&decl->link); } | fully_specified_type any_identifier '[' ']' @@ -1010,7 +1011,7 @@ single_declaration: ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, NULL); $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->declarations.push_tail(&decl->link); } | fully_specified_type any_identifier '[' constant_expression ']' @@ -1019,7 +1020,7 @@ single_declaration: ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, NULL); $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->declarations.push_tail(&decl->link); } | fully_specified_type any_identifier '[' ']' '=' initializer @@ -1028,7 +1029,7 @@ single_declaration: ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, $6); $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->declarations.push_tail(&decl->link); } | fully_specified_type any_identifier '[' constant_expression ']' '=' initializer @@ -1037,7 +1038,7 @@ single_declaration: ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, $7); $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->declarations.push_tail(&decl->link); } | fully_specified_type any_identifier '=' initializer @@ -1046,7 +1047,7 @@ single_declaration: ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4); $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->declarations.push_tail(&decl->link); } | INVARIANT variable_identifier // Vertex only. @@ -1055,7 +1056,7 @@ single_declaration: ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL); $$ = new(ctx) ast_declarator_list(NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->invariant = true; $$->declarations.push_tail(&decl->link); @@ -1067,14 +1068,14 @@ fully_specified_type: { void *ctx = state; $$ = new(ctx) ast_fully_specified_type(); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->specifier = $1; } | type_qualifier type_specifier { void *ctx = state; $$ = new(ctx) ast_fully_specified_type(); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->qualifier = $1; $$->specifier = $2; } @@ -1347,19 +1348,19 @@ type_specifier_nonarray: { void *ctx = state; $$ = new(ctx) ast_type_specifier($1); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | struct_specifier { void *ctx = state; $$ = new(ctx) ast_type_specifier($1); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | TYPE_IDENTIFIER { void *ctx = state; $$ = new(ctx) ast_type_specifier($1); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -1456,14 +1457,14 @@ struct_specifier: { void *ctx = state; $$ = new(ctx) ast_struct_specifier($2, $4); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); state->symbols->add_type($2, glsl_type::void_type); } | STRUCT '{' struct_declaration_list '}' { void *ctx = state; $$ = new(ctx) ast_struct_specifier(NULL, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -1485,11 +1486,11 @@ struct_declaration: { void *ctx = state; ast_fully_specified_type *type = new(ctx) ast_fully_specified_type(); - type->set_location(yylloc); + type->set_location(yylloc, ctx); type->specifier = $1; $$ = new(ctx) ast_declarator_list(type); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->declarations.push_degenerate_list_at_head(& $2->link); } @@ -1513,14 +1514,14 @@ struct_declarator: { void *ctx = state; $$ = new(ctx) ast_declaration($1, false, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); state->symbols->add_variable(new(state) ir_variable(NULL, $1, ir_var_auto)); } | any_identifier '[' constant_expression ']' { void *ctx = state; $$ = new(ctx) ast_declaration($1, true, $3, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -1553,7 +1554,7 @@ compound_statement: { void *ctx = state; $$ = new(ctx) ast_compound_statement(true, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | '{' { @@ -1563,7 +1564,7 @@ compound_statement: { void *ctx = state; $$ = new(ctx) ast_compound_statement(true, $3); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); state->symbols->pop_scope(); } ; @@ -1578,13 +1579,13 @@ compound_statement_no_new_scope: { void *ctx = state; $$ = new(ctx) ast_compound_statement(false, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | '{' statement_list '}' { void *ctx = state; $$ = new(ctx) ast_compound_statement(false, $2); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -1615,13 +1616,13 @@ expression_statement: { void *ctx = state; $$ = new(ctx) ast_expression_statement(NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | expression ';' { void *ctx = state; $$ = new(ctx) ast_expression_statement($1); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -1630,7 +1631,7 @@ selection_statement: { $$ = new(state) ast_selection_statement($3, $5.then_statement, $5.else_statement); - $$->set_location(yylloc); + $$->set_location(yylloc, state); } ; @@ -1657,8 +1658,8 @@ condition: void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4); ast_declarator_list *declarator = new(ctx) ast_declarator_list($1); - decl->set_location(yylloc); - declarator->set_location(yylloc); + decl->set_location(yylloc, ctx); + declarator->set_location(yylloc, ctx); declarator->declarations.push_tail(&decl->link); $$ = declarator; @@ -1673,7 +1674,7 @@ switch_statement: SWITCH '(' expression ')' switch_body { $$ = new(state) ast_switch_statement($3, $5); - $$->set_location(yylloc); + $$->set_location(yylloc, state); } ; @@ -1681,12 +1682,12 @@ switch_body: '{' '}' { $$ = new(state) ast_switch_body(NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, state); } | '{' case_statement_list '}' { $$ = new(state) ast_switch_body($2); - $$->set_location(yylloc); + $$->set_location(yylloc, state); } ; @@ -1694,12 +1695,12 @@ case_label: CASE expression ':' { $$ = new(state) ast_case_label($2); - $$->set_location(yylloc); + $$->set_location(yylloc, state); } | DEFAULT ':' { $$ = new(state) ast_case_label(NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, state); } ; @@ -1710,7 +1711,7 @@ case_label_list: labels->labels.push_tail(& $1->link); $$ = labels; - $$->set_location(yylloc); + $$->set_location(yylloc, state); } | case_label_list case_label { @@ -1723,7 +1724,7 @@ case_statement: case_label_list statement { ast_case_statement *stmts = new(state) ast_case_statement($1); - stmts->set_location(yylloc); + stmts->set_location(yylloc, state); stmts->stmts.push_tail(& $2->link); $$ = stmts; @@ -1739,7 +1740,7 @@ case_statement_list: case_statement { ast_case_statement_list *cases= new(state) ast_case_statement_list(); - cases->set_location(yylloc); + cases->set_location(yylloc, state); cases->cases.push_tail(& $1->link); $$ = cases; @@ -1757,21 +1758,21 @@ iteration_statement: void *ctx = state; $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while, NULL, $3, NULL, $5); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | DO statement WHILE '(' expression ')' ';' { void *ctx = state; $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while, NULL, $5, NULL, $2); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | FOR '(' for_init_statement for_rest_statement ')' statement_no_new_scope { void *ctx = state; $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for, $3, $4.cond, $4.rest, $6); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -1807,31 +1808,31 @@ jump_statement: { void *ctx = state; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | BREAK ';' { void *ctx = state; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | RETURN ';' { void *ctx = state; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | RETURN expression ';' { void *ctx = state; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, $2); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } | DISCARD ';' // Fragment shader only. { void *ctx = state; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); } ; @@ -1846,7 +1847,7 @@ function_definition: { void *ctx = state; $$ = new(ctx) ast_function_definition(); - $$->set_location(yylloc); + $$->set_location(yylloc, ctx); $$->prototype = $1; $$->body = $2; diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index 21c3c6e..9954952 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -141,11 +141,18 @@ _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state, { va_list ap; + char sbuf[12]; + const char *source = locp->source; + if (!source) { + source = sbuf; + sprintf (sbuf, "%u", locp->source_id); + } + state->error = true; assert(state->info_log != NULL); - ralloc_asprintf_append(&state->info_log, "%u:%u(%u): error: ", - locp->source, + ralloc_asprintf_append(&state->info_log, "%s:%u(%u): error: ", + source, locp->first_line, locp->first_column); va_start(ap, fmt); @@ -161,9 +168,16 @@ _mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state, { va_list ap; + char sbuf[12]; + const char *source = locp->source; + if (!source) { + source = sbuf; + sprintf (sbuf, "%u", locp->source_id); + } + assert(state->info_log != NULL); - ralloc_asprintf_append(&state->info_log, "%u:%u(%u): warning: ", - locp->source, + ralloc_asprintf_append(&state->info_log, "%s:%u(%u): warning: ", + source, locp->first_line, locp->first_column); va_start(ap, fmt); @@ -464,6 +478,7 @@ ast_node::print(void) const ast_node::ast_node(void) { + this->location.source_id = 0; this->location.source = 0; this->location.line = 0; this->location.column = 0; diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h index 55676f5..8c8ab8e 100644 --- a/src/glsl/glsl_parser_extras.h +++ b/src/glsl/glsl_parser_extras.h @@ -212,6 +212,10 @@ struct _mesa_glsl_parse_state { /** Shaders containing built-in functions that are used for linking. */ struct gl_shader *builtins_to_link[16]; unsigned num_builtins_to_link; + + /** Source currently being parsed */ + unsigned source_id; + char *source; }; typedef struct YYLTYPE { @@ -219,7 +223,8 @@ typedef struct YYLTYPE { int first_column; int last_line; int last_column; - unsigned source; + unsigned source_id; + char *source; } YYLTYPE; # define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_TRIVIAL 1 @@ -232,6 +237,8 @@ do { \ (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ (Current).last_column = YYRHSLOC(Rhs, N).last_column; \ + (Current).source = YYRHSLOC(Rhs, 1).source; \ + (Current).source_id = YYRHSLOC(Rhs, 1).source_id; \ } \ else \ { \ @@ -239,8 +246,9 @@ do { \ YYRHSLOC(Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC(Rhs, 0).last_column; \ + (Current).source = YYRHSLOC(Rhs, 0).source; \ + (Current).source_id = YYRHSLOC(Rhs, 0).source_id; \ } \ - (Current).source = 0; \ } while (0) extern void _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state, @@ -296,7 +304,9 @@ extern "C" { #endif extern int preprocess(void *ctx, const char **shader, char **info_log, - const struct gl_extensions *extensions, int api); + const struct gl_extensions *extensions, int api, + const char *base_path, + const char *(*get_string)(void *param, const char *), void *param); extern void _mesa_destroy_shader_compiler(void); extern void _mesa_destroy_shader_compiler_caches(void); diff --git a/src/glsl/main.cpp b/src/glsl/main.cpp index d43bf1a..5a005a3 100644 --- a/src/glsl/main.cpp +++ b/src/glsl/main.cpp @@ -21,6 +21,7 @@ * DEALINGS IN THE SOFTWARE. */ #include <getopt.h> +#include <unistd.h> #include "ast.h" #include "glsl_parser_extras.h" @@ -129,14 +130,17 @@ usage_fail(const char *name) void -compile_shader(struct gl_context *ctx, struct gl_shader *shader) +compile_shader(struct gl_context *ctx, struct gl_shader *shader, + const char *base_path, + const char *(*get_string)(void *param, const char *), void *param) { struct _mesa_glsl_parse_state *state = new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); const char *source = shader->Source; state->error = preprocess(state, &source, &state->info_log, - state->extensions, ctx->API) != 0; + state->extensions, ctx->API, + base_path, get_string, param) != 0; if (!state->error) { _mesa_glsl_lexer_ctor(state, source); @@ -198,6 +202,14 @@ compile_shader(struct gl_context *ctx, struct gl_shader *shader) return; } +static const char * +get_string(void *ctx, const char *name) +{ + return load_text_file(ctx, name); +} + +extern "C" char *glcpp_canonicalize_path(void *ctx, const char *base_path, const char *file_name); + int main(int argc, char **argv) { @@ -222,6 +234,8 @@ main(int argc, char **argv) assert(whole_program != NULL); whole_program->InfoLog = ralloc_strdup(whole_program, ""); + char *cur_dir = get_current_dir_name(); + for (/* empty */; argc > optind; optind++) { whole_program->Shaders = reralloc(whole_program, whole_program->Shaders, @@ -247,13 +261,15 @@ main(int argc, char **argv) else usage_fail(argv[0]); + shader->Source = load_text_file(whole_program, argv[optind]); if (shader->Source == NULL) { printf("File \"%s\" does not exist.\n", argv[optind]); exit(EXIT_FAILURE); } - compile_shader(ctx, shader); + char *base_path = glcpp_canonicalize_path(whole_program, cur_dir, argv[optind]); + compile_shader(ctx, shader, base_path, get_string, whole_program); if (!shader->CompileStatus) { printf("Info log for %s:\n%s\n", argv[optind], shader->InfoLog); @@ -262,6 +278,8 @@ main(int argc, char **argv) } } + free(cur_dir); + if ((status == EXIT_SUCCESS) && do_link) { link_shaders(ctx, whole_program); status = (whole_program->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE; diff --git a/src/glsl/test_optpass.cpp b/src/glsl/test_optpass.cpp index 6abafb5..e3c7e1c 100644 --- a/src/glsl/test_optpass.cpp +++ b/src/glsl/test_optpass.cpp @@ -219,7 +219,7 @@ int test_optpass(int argc, char **argv) shader->Source = input.c_str(); const char *source = shader->Source; state->error = preprocess(state, &source, &state->info_log, - state->extensions, ctx->API) != 0; + state->extensions, ctx->API, 0, 0, 0) != 0; if (!state->error) { _mesa_glsl_lexer_ctor(state, source); diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index 697313f..dd0e0e9 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -3322,7 +3322,7 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader) } state->error = preprocess(state, &source, &state->info_log, - &ctx->Extensions, ctx->API); + &ctx->Extensions, ctx->API, 0, 0, 0); if (ctx->Shader.Flags & GLSL_DUMP) { printf("GLSL source for %s shader %d:\n", -- 1.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev