summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Arceri <tarceri@itsqueeze.com>2019-08-14 14:24:31 +1000
committerTimothy Arceri <tarceri@itsqueeze.com>2019-11-20 05:05:55 +0000
commit67b32190f3c953c5b7091d76ddeff95c0cbfb439 (patch)
treef80299cbb521fb547dd685dd46a5aae6b06bc7ef
parent2497c517176c2c9bd418d7d54eaef9aba0711727 (diff)
glsl: add ARB_shading_language_include support to #line
From the ARB_shading_language_include spec: "#line must have, after macro substitution, one of the following forms: #line <line> #line <line> <source-string-number> #line <line> "<path>" where <line> and <source-string-number> are constant integer expressions and <path> is a valid string for a path supplied in the #include directive. After processing this directive (including its new-line), the implementation will behave as if it is compiling at line number <line> and source string number <source-string-number> or <path> path. Subsequent source strings will be numbered sequentially, until another #line directive overrides that numbering." Reviewed-by: Witold Baryluk <witold.baryluk@gmail.com>
-rw-r--r--src/compiler/glsl/ast.h4
-rw-r--r--src/compiler/glsl/glcpp/glcpp-lex.l5
-rw-r--r--src/compiler/glsl/glcpp/glcpp-parse.y15
-rw-r--r--src/compiler/glsl/glsl_lexer.ll47
-rw-r--r--src/compiler/glsl/glsl_parser.yy1
-rw-r--r--src/compiler/glsl/glsl_parser_extras.cpp14
-rw-r--r--src/compiler/glsl/glsl_parser_extras.h2
7 files changed, 80 insertions, 8 deletions
diff --git a/src/compiler/glsl/ast.h b/src/compiler/glsl/ast.h
index f07a14bce8f..67b258ce538 100644
--- a/src/compiler/glsl/ast.h
+++ b/src/compiler/glsl/ast.h
@@ -77,6 +77,7 @@ public:
{
struct YYLTYPE locp;
+ locp.path = this->location.path;
locp.source = this->location.source;
locp.first_line = this->location.first_line;
locp.first_column = this->location.first_column;
@@ -93,6 +94,7 @@ public:
*/
void set_location(const struct YYLTYPE &locp)
{
+ this->location.path = locp.path;
this->location.source = locp.source;
this->location.first_line = locp.first_line;
this->location.first_column = locp.first_column;
@@ -107,6 +109,7 @@ public:
*/
void set_location_range(const struct YYLTYPE &begin, const struct YYLTYPE &end)
{
+ this->location.path = begin.path;
this->location.source = begin.source;
this->location.first_line = begin.first_line;
this->location.last_line = end.last_line;
@@ -118,6 +121,7 @@ public:
* Source location of the AST node.
*/
struct {
+ char *path; /**< GLSL shader include path. */
unsigned source; /**< GLSL source number. */
unsigned first_line; /**< First line number within the source string. */
unsigned first_column; /**< First column in the first line. */
diff --git a/src/compiler/glsl/glcpp/glcpp-lex.l b/src/compiler/glsl/glcpp/glcpp-lex.l
index f7003da0cc8..47ecb7b55b1 100644
--- a/src/compiler/glsl/glcpp/glcpp-lex.l
+++ b/src/compiler/glsl/glcpp/glcpp-lex.l
@@ -202,6 +202,7 @@ DIGITS [0-9][0-9]*
DECIMAL_INTEGER [1-9][0-9]*[uU]?
OCTAL_INTEGER 0[0-7]*[uU]?
HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
+PATH ["][]^./ _A-Za-z0-9+*%[(){}|&~=!:;,?-]*["]
%%
@@ -558,6 +559,10 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
}
}
+{PATH} {
+ RETURN_STRING_TOKEN (PATH);
+}
+
/* We preserve all newlines, even between #if 0..#endif, so no
skipping.. */
<*>{NEWLINE} {
diff --git a/src/compiler/glsl/glcpp/glcpp-parse.y b/src/compiler/glsl/glcpp/glcpp-parse.y
index 51bc85dcee7..b975e8b3f40 100644
--- a/src/compiler/glsl/glcpp/glcpp-parse.y
+++ b/src/compiler/glsl/glcpp/glcpp-parse.y
@@ -174,11 +174,11 @@ add_builtin_define(glcpp_parser_t *parser, const char *name, int value);
/* We use HASH_TOKEN, DEFINE_TOKEN and VERSION_TOKEN (as opposed to
* HASH, DEFINE, and VERSION) to avoid conflicts with other symbols,
* (such as the <HASH> and <DEFINE> start conditions in the lexer). */
-%token DEFINED ELIF_EXPANDED HASH_TOKEN DEFINE_TOKEN FUNC_IDENTIFIER OBJ_IDENTIFIER ELIF ELSE ENDIF ERROR_TOKEN IF IFDEF IFNDEF LINE PRAGMA UNDEF VERSION_TOKEN GARBAGE IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE PLUS_PLUS MINUS_MINUS
+%token DEFINED ELIF_EXPANDED HASH_TOKEN DEFINE_TOKEN FUNC_IDENTIFIER OBJ_IDENTIFIER ELIF ELSE ENDIF ERROR_TOKEN IF IFDEF IFNDEF LINE PRAGMA UNDEF VERSION_TOKEN GARBAGE IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE PLUS_PLUS MINUS_MINUS PATH
%token PASTE
%type <ival> INTEGER operator SPACE integer_constant version_constant
%type <expression_value> expression
-%type <str> IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER ERROR_TOKEN PRAGMA
+%type <str> IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER ERROR_TOKEN PRAGMA PATH
%type <string_list> identifier_list
%type <token> preprocessing_token
%type <token_list> pp_tokens replacement_list text_line
@@ -238,6 +238,13 @@ expanded_line:
"#line %" PRIiMAX " %" PRIiMAX "\n",
$2, $3);
}
+| LINE_EXPANDED integer_constant PATH NEWLINE {
+ parser->has_new_line_number = 1;
+ parser->new_line_number = $2;
+ _mesa_string_buffer_printf(parser->output,
+ "#line %" PRIiMAX " %s\n",
+ $2, $3);
+ }
;
define:
@@ -706,6 +713,10 @@ preprocessing_token:
$$ = _token_create_str (parser, INTEGER_STRING, $1);
$$->location = yylloc;
}
+| PATH {
+ $$ = _token_create_str (parser, PATH, $1);
+ $$->location = yylloc;
+ }
| operator {
$$ = _token_create_ival (parser, $1, $1);
$$->location = yylloc;
diff --git a/src/compiler/glsl/glsl_lexer.ll b/src/compiler/glsl/glsl_lexer.ll
index 43bd2b23ec4..8c59e1d748f 100644
--- a/src/compiler/glsl/glsl_lexer.ll
+++ b/src/compiler/glsl/glsl_lexer.ll
@@ -45,7 +45,8 @@ static int classify_identifier(struct _mesa_glsl_parse_state *, const char *,
yylloc->last_column = yycolumn + 1; \
} while(0);
-#define YY_USER_INIT yylineno = 0; yycolumn = 0; yylloc->source = 0;
+#define YY_USER_INIT yylineno = 0; yycolumn = 0; yylloc->source = 0; \
+ yylloc->path = NULL;
/* A macro for handling reserved words and keywords across language versions.
*
@@ -226,6 +227,7 @@ INT ({DEC_INT}|{HEX_INT}|{OCT_INT})
SPC [ \t]*
SPCP [ \t]+
HASH ^{SPC}#{SPC}
+PATH ["][./ _A-Za-z0-9]*["]
%%
[ \r\t]+ ;
@@ -257,7 +259,50 @@ HASH ^{SPC}#{SPC}
yylineno--;
yylloc->source = strtol(ptr, NULL, 0);
+ yylloc->path = NULL;
}
+{HASH}line{SPCP}{INT}{SPCP}{PATH}{SPC}$ {
+ if (!yyextra->ARB_shading_language_include_enable) {
+ struct _mesa_glsl_parse_state *state = yyextra;
+ _mesa_glsl_error(yylloc, state,
+ "ARB_shading_language_include required "
+ "to use #line <line> \"<path>\"");
+ }
+
+ /* 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;
+
+ /* From GLSL 3.30 and GLSL ES on, after processing the
+ * line directive (including its new-line), the implementation
+ * will behave as if it is compiling at the line number passed
+ * as argument. It was line number + 1 in older specifications.
+ */
+ if (yyextra->is_version(330, 100))
+ yylineno--;
+
+ while (isspace(*ptr))
+ ptr++;
+
+ /* Skip over leading " */
+ ptr++;
+
+ char *end = strrchr(ptr, '"');
+ int path_len = (end - ptr) + 1;
+ void *mem_ctx = yyextra->linalloc;
+ yylloc->path = (char *) linear_alloc_child(mem_ctx, path_len);
+ memcpy(yylloc->path, ptr, path_len);
+ yylloc->path[path_len - 1] = '\0';
+ }
{HASH}line{SPCP}{INT}{SPC}$ {
/* Eat characters until the first digit is
* encountered
diff --git a/src/compiler/glsl/glsl_parser.yy b/src/compiler/glsl/glsl_parser.yy
index edf421d9053..048af1f0857 100644
--- a/src/compiler/glsl/glsl_parser.yy
+++ b/src/compiler/glsl/glsl_parser.yy
@@ -91,6 +91,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2,
@$.last_line = 1;
@$.last_column = 1;
@$.source = 0;
+ @$.path = NULL;
}
%lex-param {struct _mesa_glsl_parse_state *state}
diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp
index e457d63b988..b1573460080 100644
--- a/src/compiler/glsl/glsl_parser_extras.cpp
+++ b/src/compiler/glsl/glsl_parser_extras.cpp
@@ -495,11 +495,15 @@ _mesa_glsl_msg(const YYLTYPE *locp, _mesa_glsl_parse_state *state,
/* Get the offset that the new message will be written to. */
int msg_offset = strlen(state->info_log);
- ralloc_asprintf_append(&state->info_log, "%u:%u(%u): %s: ",
- locp->source,
- locp->first_line,
- locp->first_column,
- error ? "error" : "warning");
+ if (locp->path) {
+ ralloc_asprintf_append(&state->info_log, "\"%s\"", locp->path);
+ } else {
+ ralloc_asprintf_append(&state->info_log, "%u", locp->source);
+ }
+ ralloc_asprintf_append(&state->info_log, ":%u(%u): %s: ",
+ locp->first_line, locp->first_column,
+ error ? "error" : "warning");
+
ralloc_vasprintf_append(&state->info_log, fmt, ap);
const char *const msg = &state->info_log[msg_offset];
diff --git a/src/compiler/glsl/glsl_parser_extras.h b/src/compiler/glsl/glsl_parser_extras.h
index 33db8b5b656..444a51dfdb5 100644
--- a/src/compiler/glsl/glsl_parser_extras.h
+++ b/src/compiler/glsl/glsl_parser_extras.h
@@ -68,6 +68,8 @@ typedef struct YYLTYPE {
int last_line;
int last_column;
unsigned source;
+ /* Path for ARB_shading_language_include include source */
+ char *path;
} YYLTYPE;
# define YYLTYPE_IS_DECLARED 1
# define YYLTYPE_IS_TRIVIAL 1