[Mesa-dev] [PATCH 1/2] glsl: Support GL_ARB_shading_language_include internally.
Olivier Galibert
galibert at pobox.com
Wed Apr 11 01:46:51 PDT 2012
No hookup with GL yet. Planned to be used to simplify profiles.
Signed-off-by: Olivier Galibert <galibert at 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
More information about the mesa-dev
mailing list