%}
%pure-parser
-%locations
%error-verbose
+%locations
+%initial-action {
+ @$.first_line = 1;
+ @$.first_column = 1;
+ @$.last_line = 1;
+ @$.last_column = 1;
+ @$.source = 0;
+}
+
%lex-param {void *scanner}
%parse-param {struct _mesa_glsl_parse_state *state}
-%name-prefix "_mesa_glsl_"
%union {
int n;
unsigned i;
} type_qualifier;
- struct ast_node *node;
- struct ast_type_specifier *type_specifier;
- struct ast_fully_specified_type *fully_specified_type;
- struct ast_function *function;
- struct ast_parameter_declarator *parameter_declarator;
- struct ast_function_definition *function_definition;
- struct ast_compound_statement *compound_statement;
- struct ast_expression *expression;
- struct ast_declarator_list *declarator_list;
- struct ast_struct_specifier *struct_specifier;
- struct ast_declaration *declaration;
+ ast_node *node;
+ ast_type_specifier *type_specifier;
+ ast_fully_specified_type *fully_specified_type;
+ ast_function *function;
+ ast_parameter_declarator *parameter_declarator;
+ ast_function_definition *function_definition;
+ ast_compound_statement *compound_statement;
+ ast_expression *expression;
+ ast_declarator_list *declarator_list;
+ ast_struct_specifier *struct_specifier;
+ ast_declaration *declaration;
struct {
- struct ast_node *cond;
- struct ast_expression *rest;
+ ast_node *cond;
+ ast_expression *rest;
} for_rest_statement;
+
+ struct {
+ ast_node *then_statement;
+ ast_node *else_statement;
+ } selection_rest_statement;
}
-%token ATTRIBUTE CONST_TOK BOOL FLOAT INT UINT
+%token ATTRIBUTE CONST_TOK BOOL_TOK FLOAT_TOK INT_TOK UINT_TOK
%token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT
%token BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4
-%token MAT2 MAT3 MAT4 CENTROID IN OUT INOUT UNIFORM VARYING
+%token CENTROID IN_TOK OUT_TOK INOUT_TOK UNIFORM VARYING
%token NOPERSPECTIVE FLAT SMOOTH
%token MAT2X2 MAT2X3 MAT2X4
%token MAT3X2 MAT3X3 MAT3X4
%token SAMPLER2DARRAYSHADOW ISAMPLER1D ISAMPLER2D ISAMPLER3D ISAMPLERCUBE
%token ISAMPLER1DARRAY ISAMPLER2DARRAY USAMPLER1D USAMPLER2D USAMPLER3D
%token USAMPLERCUBE USAMPLER1DARRAY USAMPLER2DARRAY
-%token STRUCT VOID WHILE
+%token STRUCT VOID_TOK WHILE
%token <identifier> IDENTIFIER
%token <real> FLOATCONSTANT
%token <n> INTCONSTANT UINTCONSTANT BOOLCONSTANT
%token MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
%token SUB_ASSIGN
%token INVARIANT
-%token LOWP MEDIUMP HIGHP PRECISION
+%token LOWP MEDIUMP HIGHP SUPERP PRECISION
-%token VERSION EXTENSION LINE PRAGMA COLON EOL INTERFACE OUTPUT
+%token VERSION EXTENSION LINE COLON EOL INTERFACE OUTPUT
+%token PRAGMA_DEBUG_ON PRAGMA_DEBUG_OFF
+%token PRAGMA_OPTIMIZE_ON PRAGMA_OPTIMIZE_OFF
+%token LAYOUT_TOK
/* Reserved words that are not actually used in the grammar.
*/
-%token ASM CLASS UNION ENUM TYPEDEF TEMPLATE THIS PACKED GOTO
+%token ASM CLASS UNION ENUM TYPEDEF TEMPLATE THIS PACKED_TOK GOTO
%token INLINE_TOK NOINLINE VOLATILE PUBLIC_TOK STATIC EXTERN EXTERNAL
-%token LONG SHORT DOUBLE HALF FIXED UNSIGNED INPUT OUPTUT
+%token LONG_TOK SHORT_TOK DOUBLE_TOK HALF FIXED_TOK UNSIGNED INPUT_TOK OUPTUT
%token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4
%token SAMPLER2DRECT SAMPLER3DRECT SAMPLER2DRECTSHADOW
%token SIZEOF CAST NAMESPACE USING
+%token ERROR_TOK
+
+%token COMMON PARTITION ACTIVE SAMPLERBUFFER FILTER
+%token IMAGE1D IMAGE2D IMAGE3D IMAGECUBE IMAGE1DARRAY IMAGE2DARRAY
+%token IIMAGE1D IIMAGE2D IIMAGE3D IIMAGECUBE IIMAGE1DARRAY IIMAGE2DARRAY
+%token UIMAGE1D UIMAGE2D UIMAGE3D UIMAGECUBE UIMAGE1DARRAY UIMAGE2DARRAY
+%token IMAGE1DSHADOW IMAGE2DSHADOW IMAGEBUFFER IIMAGEBUFFER UIMAGEBUFFER
+%token ROW_MAJOR
+
%type <identifier> variable_identifier
%type <node> statement
%type <node> statement_list
%type <node> simple_statement
-%type <node> statement_matched
-%type <node> statement_unmatched
%type <n> precision_qualifier
%type <type_qualifier> type_qualifier
%type <type_qualifier> storage_qualifier
%type <type_qualifier> interpolation_qualifier
+%type <type_qualifier> layout_qualifier
+%type <type_qualifier> layout_qualifier_id_list layout_qualifier_id
%type <type_specifier> type_specifier
%type <type_specifier> type_specifier_no_prec
%type <type_specifier> type_specifier_nonarray
%type <declarator_list> struct_declaration
%type <declaration> struct_declarator
%type <declaration> struct_declarator_list
-%type <node> selection_statement_matched
-%type <node> selection_statement_unmatched
+%type <node> selection_statement
+%type <selection_rest_statement> selection_rest_statement
%type <node> iteration_statement
%type <node> condition
%type <node> conditionopt
;
version_statement:
- /* blank - no #version specified */
- {
- state->language_version = 110;
- }
+ /* blank - no #version specified: defaults are already set */
| VERSION INTCONSTANT EOL
{
switch ($2) {
+ case 100:
+ state->es_shader = true;
case 110:
case 120:
case 130:
}
;
+pragma_statement:
+ PRAGMA_DEBUG_ON EOL
+ | PRAGMA_DEBUG_OFF EOL
+ | PRAGMA_OPTIMIZE_ON EOL
+ | PRAGMA_OPTIMIZE_OFF EOL
+ ;
+
extension_statement_list:
| extension_statement_list extension_statement
}
| function_call
{
- /* Function call parameters used to be stored as a circular list in
- * subexpressions[1]. They are now stored as a regular list in
- * expressions. This assertion validates that the old code was
- * correctly converted. It can eventually be removed.
- */
- assert($1->subexpressions[1] == NULL);
$$ = $1;
}
| postfix_expression '.' IDENTIFIER
;
function_call_header_no_parameters:
- function_call_header VOID
+ function_call_header VOID_TOK
| function_call_header
;
;
parameter_qualifier:
- /* empty */ { $$.i = 0; }
- | IN { $$.i = 0; $$.q.in = 1; }
- | OUT { $$.i = 0; $$.q.out = 1; }
- | INOUT { $$.i = 0; $$.q.in = 1; $$.q.out = 1; }
+ /* empty */
+ {
+ memset(& $$, 0, sizeof($$));
+ }
+ | IN_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.q.in = 1;
+ }
+ | OUT_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.q.out = 1;
+ }
+ | INOUT_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.q.in = 1; $$.q.out = 1;
+ }
;
parameter_type_specifier:
}
;
+layout_qualifier:
+ LAYOUT_TOK '(' layout_qualifier_id_list ')'
+ {
+ $$ = $3;
+ }
+ ;
+
+layout_qualifier_id_list:
+ layout_qualifier_id
+ | layout_qualifier_id_list ',' layout_qualifier_id
+ {
+ $$.i = $1.i | $3.i;
+ }
+ ;
+
+layout_qualifier_id:
+ IDENTIFIER
+ {
+ bool got_one = false;
+
+ memset(& $$, 0, sizeof($$));
+
+ if (state->ARB_fragment_coord_conventions_enable) {
+ if (strcmp($1, "origin_upper_left") == 0) {
+ got_one = true;
+ $$.q.origin_upper_left = 1;
+ } else if (strcmp($1, "pixel_center_integer") == 0) {
+ got_one = true;
+ $$.q.pixel_center_integer = 1;
+ }
+ }
+
+ /* If the identifier didn't match any known layout identifiers,
+ * emit an error.
+ */
+ if (!got_one) {
+ _mesa_glsl_error(& @1, state, "unrecognized layout identifier "
+ "`%s'\n", $1);
+ YYERROR;
+ } else if (state->ARB_fragment_coord_conventions_warn) {
+ _mesa_glsl_warning(& @1, state,
+ "GL_ARB_fragment_coord_conventions layout "
+ "identifier `%s' used\n", $1);
+ }
+ }
+ ;
+
interpolation_qualifier:
- SMOOTH { $$.i = 0; $$.q.smooth = 1; }
- | FLAT { $$.i = 0; $$.q.flat = 1; }
- | NOPERSPECTIVE { $$.i = 0; $$.q.noperspective = 1; }
+ SMOOTH
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.q.smooth = 1;
+ }
+ | FLAT
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.q.flat = 1;
+ }
+ | NOPERSPECTIVE
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.q.noperspective = 1;
+ }
;
parameter_type_qualifier:
- CONST_TOK { $$.i = 0; $$.q.constant = 1; }
+ CONST_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.q.constant = 1;
+ }
;
type_qualifier:
storage_qualifier
- | interpolation_qualifier type_qualifier
+ | layout_qualifier
+ | layout_qualifier storage_qualifier
{
$$.i = $1.i | $2.i;
}
- | INVARIANT type_qualifier
+ | interpolation_qualifier
+ | interpolation_qualifier storage_qualifier
+ {
+ $$.i = $1.i | $2.i;
+ }
+ | INVARIANT storage_qualifier
{
$$ = $2;
$$.q.invariant = 1;
}
+ | INVARIANT interpolation_qualifier storage_qualifier
+ {
+ $$.i = $2.i | $3.i;
+ $$.q.invariant = 1;
+ }
+ | INVARIANT
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.q.invariant = 1;
+ }
;
storage_qualifier:
- CONST_TOK { $$.i = 0; $$.q.constant = 1; }
- | ATTRIBUTE { $$.i = 0; $$.q.attribute = 1; }
- | VARYING { $$.i = 0; $$.q.varying = 1; }
- | CENTROID VARYING { $$.i = 0; $$.q.centroid = 1; $$.q.varying = 1; }
- | IN { $$.i = 0; $$.q.in = 1; }
- | OUT { $$.i = 0; $$.q.out = 1; }
- | CENTROID IN { $$.i = 0; $$.q.centroid = 1; $$.q.in = 1; }
- | CENTROID OUT { $$.i = 0; $$.q.centroid = 1; $$.q.out = 1; }
- | UNIFORM { $$.i = 0; $$.q.uniform = 1; }
+ CONST_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.q.constant = 1;
+ }
+ | ATTRIBUTE
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.q.attribute = 1;
+ }
+ | VARYING
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.q.varying = 1;
+ }
+ | CENTROID VARYING
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.q.centroid = 1; $$.q.varying = 1;
+ }
+ | IN_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.q.in = 1;
+ }
+ | OUT_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.q.out = 1;
+ }
+ | CENTROID IN_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.q.centroid = 1; $$.q.in = 1;
+ }
+ | CENTROID OUT_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.q.centroid = 1; $$.q.out = 1;
+ }
+ | UNIFORM
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.q.uniform = 1;
+ }
;
type_specifier:
;
basic_type_specifier_nonarray:
- VOID { $$ = ast_void; }
- | FLOAT { $$ = ast_float; }
- | INT { $$ = ast_int; }
- | UINT { $$ = ast_uint; }
- | BOOL { $$ = ast_bool; }
+ VOID_TOK { $$ = ast_void; }
+ | FLOAT_TOK { $$ = ast_float; }
+ | INT_TOK { $$ = ast_int; }
+ | UINT_TOK { $$ = ast_uint; }
+ | BOOL_TOK { $$ = ast_bool; }
| VEC2 { $$ = ast_vec2; }
| VEC3 { $$ = ast_vec3; }
| VEC4 { $$ = ast_vec4; }
| UVEC2 { $$ = ast_uvec2; }
| UVEC3 { $$ = ast_uvec3; }
| UVEC4 { $$ = ast_uvec4; }
- | MAT2 { $$ = ast_mat2; }
- | MAT3 { $$ = ast_mat3; }
- | MAT4 { $$ = ast_mat4; }
| MAT2X2 { $$ = ast_mat2; }
| MAT2X3 { $$ = ast_mat2x3; }
| MAT2X4 { $$ = ast_mat2x4; }
;
precision_qualifier:
- HIGHP {
- if (state->language_version < 130)
- _mesa_glsl_error(& @1, state,
- "precission qualifier forbidden "
- "in GLSL %d.%d (1.30 or later "
- "required)\n",
- state->language_version / 100,
- state->language_version % 100);
-
- $$ = ast_precision_high;
- }
- | MEDIUMP {
- if (state->language_version < 130)
- _mesa_glsl_error(& @1, state,
- "precission qualifier forbidden "
- "in GLSL %d.%d (1.30 or later "
- "required)\n",
- state->language_version / 100,
- state->language_version % 100);
-
- $$ = ast_precision_medium;
- }
- | LOWP {
- if (state->language_version < 130)
- _mesa_glsl_error(& @1, state,
- "precission qualifier forbidden "
- "in GLSL %d.%d (1.30 or later "
- "required)\n",
- state->language_version / 100,
- state->language_version % 100);
-
- $$ = ast_precision_low;
- }
+ HIGHP {
+ if (!state->es_shader && state->language_version < 130)
+ _mesa_glsl_error(& @1, state,
+ "precision qualifier forbidden "
+ "in GLSL %d.%d (1.30 or later "
+ "required)\n",
+ state->language_version / 100,
+ state->language_version % 100);
+
+ $$ = ast_precision_high;
+ }
+ | MEDIUMP {
+ if (!state->es_shader && state->language_version < 130)
+ _mesa_glsl_error(& @1, state,
+ "precision qualifier forbidden "
+ "in GLSL %d.%d (1.30 or later "
+ "required)\n",
+ state->language_version / 100,
+ state->language_version % 100);
+
+ $$ = ast_precision_medium;
+ }
+ | LOWP {
+ if (!state->es_shader && state->language_version < 130)
+ _mesa_glsl_error(& @1, state,
+ "precision qualifier forbidden "
+ "in GLSL %d.%d (1.30 or later "
+ "required)\n",
+ state->language_version / 100,
+ state->language_version % 100);
+
+ $$ = ast_precision_low;
+ }
;
struct_specifier:
struct_declaration_list:
struct_declaration
{
- $$ = (struct ast_node *) $1;
+ $$ = (ast_node *) $1;
$1->link.self_link();
}
| struct_declaration_list struct_declaration
{
- $$ = (struct ast_node *) $1;
+ $$ = (ast_node *) $1;
$$->link.insert_before(& $2->link);
}
;
// Grammar Note: labeled statements for SWITCH only; 'goto' is not
// supported.
statement:
- statement_matched
- | statement_unmatched
- ;
-
-statement_matched:
- compound_statement { $$ = (struct ast_node *) $1; }
+ compound_statement { $$ = (ast_node *) $1; }
| simple_statement
;
-statement_unmatched:
- selection_statement_unmatched
- ;
-
simple_statement:
declaration_statement
| expression_statement
- | selection_statement_matched
+ | selection_statement
| switch_statement { $$ = NULL; }
| case_label { $$ = NULL; }
| iteration_statement
;
statement_no_new_scope:
- compound_statement_no_new_scope { $$ = (struct ast_node *) $1; }
+ compound_statement_no_new_scope { $$ = (ast_node *) $1; }
| simple_statement
;
}
;
-selection_statement_matched:
- IF '(' expression ')' statement_matched ELSE statement_matched
+selection_statement:
+ IF '(' expression ')' selection_rest_statement
{
- void *ctx = state;
- $$ = new(ctx) ast_selection_statement($3, $5, $7);
+ $$ = new(state) ast_selection_statement($3, $5.then_statement,
+ $5.else_statement);
$$->set_location(yylloc);
}
;
-selection_statement_unmatched:
- IF '(' expression ')' statement_matched
+selection_rest_statement:
+ statement ELSE statement
{
- void *ctx = state;
- $$ = new(ctx) ast_selection_statement($3, $5, NULL);
- $$->set_location(yylloc);
+ $$.then_statement = $1;
+ $$.else_statement = $3;
}
- | IF '(' expression ')' statement_unmatched
+ | statement
{
- void *ctx = state;
- $$ = new(ctx) ast_selection_statement($3, $5, NULL);
- $$->set_location(yylloc);
- }
- | IF '(' expression ')' statement_matched ELSE statement_unmatched
- {
- void *ctx = state;
- $$ = new(ctx) ast_selection_statement($3, $5, $7);
- $$->set_location(yylloc);
+ $$.then_statement = $1;
+ $$.else_statement = NULL;
}
;
condition:
expression
{
- $$ = (struct ast_node *) $1;
+ $$ = (ast_node *) $1;
}
| fully_specified_type IDENTIFIER '=' initializer
{
external_declaration:
function_definition { $$ = $1; }
| declaration { $$ = $1; }
+ | pragma_statement { $$ = NULL; }
;
function_definition: