glsl: Wrap ast_type_qualifier contents in a struct in a union

This will ease adding non-bit fields in the near future.
This commit is contained in:
Ian Romanick
2010-10-05 16:38:47 -07:00
parent 5ff4cfb788
commit e24d35a5b5
5 changed files with 108 additions and 99 deletions

View File

@@ -324,23 +324,28 @@ enum {
}; };
struct ast_type_qualifier { struct ast_type_qualifier {
unsigned invariant:1; union {
unsigned constant:1; struct {
unsigned attribute:1; unsigned invariant:1;
unsigned varying:1; unsigned constant:1;
unsigned in:1; unsigned attribute:1;
unsigned out:1; unsigned varying:1;
unsigned centroid:1; unsigned in:1;
unsigned uniform:1; unsigned out:1;
unsigned smooth:1; unsigned centroid:1;
unsigned flat:1; unsigned uniform:1;
unsigned noperspective:1; unsigned smooth:1;
unsigned flat:1;
unsigned noperspective:1;
/** \name Layout qualifiers for GL_ARB_fragment_coord_conventions */ /** \name Layout qualifiers for GL_ARB_fragment_coord_conventions */
/*@{*/ /*@{*/
unsigned origin_upper_left:1; unsigned origin_upper_left:1;
unsigned pixel_center_integer:1; unsigned pixel_center_integer:1;
/*@}*/ /*@}*/
} q;
unsigned i;
} flags;
}; };
class ast_struct_specifier : public ast_node { class ast_struct_specifier : public ast_node {

View File

@@ -1552,18 +1552,19 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
struct _mesa_glsl_parse_state *state, struct _mesa_glsl_parse_state *state,
YYLTYPE *loc) YYLTYPE *loc)
{ {
if (qual->invariant) if (qual->flags.q.invariant)
var->invariant = 1; var->invariant = 1;
/* FINISHME: Mark 'in' variables at global scope as read-only. */ /* FINISHME: Mark 'in' variables at global scope as read-only. */
if (qual->constant || qual->attribute || qual->uniform if (qual->flags.q.constant || qual->flags.q.attribute
|| (qual->varying && (state->target == fragment_shader))) || qual->flags.q.uniform
|| (qual->flags.q.varying && (state->target == fragment_shader)))
var->read_only = 1; var->read_only = 1;
if (qual->centroid) if (qual->flags.q.centroid)
var->centroid = 1; var->centroid = 1;
if (qual->attribute && state->target != vertex_shader) { if (qual->flags.q.attribute && state->target != vertex_shader) {
var->type = glsl_type::error_type; var->type = glsl_type::error_type;
_mesa_glsl_error(loc, state, _mesa_glsl_error(loc, state,
"`attribute' variables may not be declared in the " "`attribute' variables may not be declared in the "
@@ -1577,7 +1578,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
* float, vec2, vec3, vec4, mat2, mat3, and mat4, or arrays of * float, vec2, vec3, vec4, mat2, mat3, and mat4, or arrays of
* these." * these."
*/ */
if (qual->varying) { if (qual->flags.q.varying) {
const glsl_type *non_array_type; const glsl_type *non_array_type;
if (var->type && var->type->is_array()) if (var->type && var->type->is_array())
@@ -1595,28 +1596,29 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
/* If there is no qualifier that changes the mode of the variable, leave /* If there is no qualifier that changes the mode of the variable, leave
* the setting alone. * the setting alone.
*/ */
if (qual->in && qual->out) if (qual->flags.q.in && qual->flags.q.out)
var->mode = ir_var_inout; var->mode = ir_var_inout;
else if (qual->attribute || qual->in else if (qual->flags.q.attribute || qual->flags.q.in
|| (qual->varying && (state->target == fragment_shader))) || (qual->flags.q.varying && (state->target == fragment_shader)))
var->mode = ir_var_in; var->mode = ir_var_in;
else if (qual->out || (qual->varying && (state->target == vertex_shader))) else if (qual->flags.q.out
|| (qual->flags.q.varying && (state->target == vertex_shader)))
var->mode = ir_var_out; var->mode = ir_var_out;
else if (qual->uniform) else if (qual->flags.q.uniform)
var->mode = ir_var_uniform; var->mode = ir_var_uniform;
if (qual->flat) if (qual->flags.q.flat)
var->interpolation = ir_var_flat; var->interpolation = ir_var_flat;
else if (qual->noperspective) else if (qual->flags.q.noperspective)
var->interpolation = ir_var_noperspective; var->interpolation = ir_var_noperspective;
else else
var->interpolation = ir_var_smooth; var->interpolation = ir_var_smooth;
var->pixel_center_integer = qual->pixel_center_integer; var->pixel_center_integer = qual->flags.q.pixel_center_integer;
var->origin_upper_left = qual->origin_upper_left; var->origin_upper_left = qual->flags.q.origin_upper_left;
if ((qual->origin_upper_left || qual->pixel_center_integer) if ((qual->flags.q.origin_upper_left || qual->flags.q.pixel_center_integer)
&& (strcmp(var->name, "gl_FragCoord") != 0)) { && (strcmp(var->name, "gl_FragCoord") != 0)) {
const char *const qual_string = (qual->origin_upper_left) const char *const qual_string = (qual->flags.q.origin_upper_left)
? "origin_upper_left" : "pixel_center_integer"; ? "origin_upper_left" : "pixel_center_integer";
_mesa_glsl_error(loc, state, _mesa_glsl_error(loc, state,
@@ -1754,13 +1756,13 @@ ast_declarator_list::hir(exec_list *instructions,
* This is relaxed in GLSL 1.30. * This is relaxed in GLSL 1.30.
*/ */
if (state->language_version < 120) { if (state->language_version < 120) {
if (this->type->qualifier.out) { if (this->type->qualifier.flags.q.out) {
_mesa_glsl_error(& loc, state, _mesa_glsl_error(& loc, state,
"`out' qualifier in declaration of `%s' " "`out' qualifier in declaration of `%s' "
"only valid for function parameters in GLSL 1.10.", "only valid for function parameters in GLSL 1.10.",
decl->identifier); decl->identifier);
} }
if (this->type->qualifier.in) { if (this->type->qualifier.flags.q.in) {
_mesa_glsl_error(& loc, state, _mesa_glsl_error(& loc, state,
"`in' qualifier in declaration of `%s' " "`in' qualifier in declaration of `%s' "
"only valid for function parameters in GLSL 1.10.", "only valid for function parameters in GLSL 1.10.",
@@ -1772,7 +1774,7 @@ ast_declarator_list::hir(exec_list *instructions,
apply_type_qualifier_to_variable(& this->type->qualifier, var, state, apply_type_qualifier_to_variable(& this->type->qualifier, var, state,
& loc); & loc);
if (this->type->qualifier.invariant) { if (this->type->qualifier.flags.q.invariant) {
if ((state->target == vertex_shader) && !(var->mode == ir_var_out || if ((state->target == vertex_shader) && !(var->mode == ir_var_out ||
var->mode == ir_var_inout)) { var->mode == ir_var_inout)) {
/* FINISHME: Note that this doesn't work for invariant on /* FINISHME: Note that this doesn't work for invariant on
@@ -1799,16 +1801,16 @@ ast_declarator_list::hir(exec_list *instructions,
/* There is no need to check for 'inout' here because the parser will /* There is no need to check for 'inout' here because the parser will
* only allow that in function parameter lists. * only allow that in function parameter lists.
*/ */
if (this->type->qualifier.attribute) { if (this->type->qualifier.flags.q.attribute) {
mode = "attribute"; mode = "attribute";
} else if (this->type->qualifier.uniform) { } else if (this->type->qualifier.flags.q.uniform) {
mode = "uniform"; mode = "uniform";
} else if (this->type->qualifier.varying) { } else if (this->type->qualifier.flags.q.varying) {
mode = "varying"; mode = "varying";
} else if (this->type->qualifier.in) { } else if (this->type->qualifier.flags.q.in) {
mode = "in"; mode = "in";
extra = " or in function parameter list"; extra = " or in function parameter list";
} else if (this->type->qualifier.out) { } else if (this->type->qualifier.flags.q.out) {
mode = "out"; mode = "out";
extra = " or in function parameter list"; extra = " or in function parameter list";
} }
@@ -1914,7 +1916,8 @@ ast_declarator_list::hir(exec_list *instructions,
/* Calculate the constant value if this is a const or uniform /* Calculate the constant value if this is a const or uniform
* declaration. * declaration.
*/ */
if (this->type->qualifier.constant || this->type->qualifier.uniform) { if (this->type->qualifier.flags.q.constant
|| this->type->qualifier.flags.q.uniform) {
ir_rvalue *new_rhs = validate_assignment(state, var->type, rhs); ir_rvalue *new_rhs = validate_assignment(state, var->type, rhs);
if (new_rhs != NULL) { if (new_rhs != NULL) {
rhs = new_rhs; rhs = new_rhs;
@@ -1924,7 +1927,7 @@ ast_declarator_list::hir(exec_list *instructions,
_mesa_glsl_error(& initializer_loc, state, _mesa_glsl_error(& initializer_loc, state,
"initializer of %s variable `%s' must be a " "initializer of %s variable `%s' must be a "
"constant expression", "constant expression",
(this->type->qualifier.constant) (this->type->qualifier.flags.q.constant)
? "const" : "uniform", ? "const" : "uniform",
decl->identifier); decl->identifier);
if (var->type->is_numeric()) { if (var->type->is_numeric()) {
@@ -1949,12 +1952,12 @@ ast_declarator_list::hir(exec_list *instructions,
if (rhs && !rhs->type->is_error()) { if (rhs && !rhs->type->is_error()) {
bool temp = var->read_only; bool temp = var->read_only;
if (this->type->qualifier.constant) if (this->type->qualifier.flags.q.constant)
var->read_only = false; var->read_only = false;
/* Never emit code to initialize a uniform. /* Never emit code to initialize a uniform.
*/ */
if (!this->type->qualifier.uniform) if (!this->type->qualifier.flags.q.uniform)
result = do_assignment(&initializer_instructions, state, result = do_assignment(&initializer_instructions, state,
lhs, rhs, lhs, rhs,
this->get_location()); this->get_location());
@@ -1968,7 +1971,7 @@ ast_declarator_list::hir(exec_list *instructions,
* its declaration, so they must be initialized when * its declaration, so they must be initialized when
* declared." * declared."
*/ */
if (this->type->qualifier.constant && decl->initializer == NULL) { if (this->type->qualifier.flags.q.constant && decl->initializer == NULL) {
_mesa_glsl_error(& loc, state, _mesa_glsl_error(& loc, state,
"const declaration of `%s' must be initialized"); "const declaration of `%s' must be initialized");
} }

View File

@@ -114,9 +114,5 @@ ast_type_specifier::ast_type_specifier(int specifier)
bool bool
ast_fully_specified_type::has_qualifiers() const ast_fully_specified_type::has_qualifiers() const
{ {
return qualifier.invariant || qualifier.constant || qualifier.attribute return this->qualifier.flags.i != 0;
|| qualifier.varying || qualifier.in
|| qualifier.out || qualifier.centroid
|| qualifier.uniform || qualifier.smooth
|| qualifier.flat || qualifier.noperspective;
} }

View File

@@ -54,10 +54,7 @@
float real; float real;
char *identifier; char *identifier;
union { struct ast_type_qualifier type_qualifier;
struct ast_type_qualifier q;
unsigned i;
} type_qualifier;
ast_node *node; ast_node *node;
ast_type_specifier *type_specifier; ast_type_specifier *type_specifier;
@@ -760,25 +757,25 @@ parameter_declarator:
parameter_declaration: parameter_declaration:
parameter_type_qualifier parameter_qualifier parameter_declarator parameter_type_qualifier parameter_qualifier parameter_declarator
{ {
$1.i |= $2.i; $1.flags.i |= $2.flags.i;
$$ = $3; $$ = $3;
$$->type->qualifier = $1.q; $$->type->qualifier = $1;
} }
| parameter_qualifier parameter_declarator | parameter_qualifier parameter_declarator
{ {
$$ = $2; $$ = $2;
$$->type->qualifier = $1.q; $$->type->qualifier = $1;
} }
| parameter_type_qualifier parameter_qualifier parameter_type_specifier | parameter_type_qualifier parameter_qualifier parameter_type_specifier
{ {
void *ctx = state; void *ctx = state;
$1.i |= $2.i; $1.flags.i |= $2.flags.i;
$$ = new(ctx) ast_parameter_declarator(); $$ = new(ctx) ast_parameter_declarator();
$$->set_location(yylloc); $$->set_location(yylloc);
$$->type = new(ctx) ast_fully_specified_type(); $$->type = new(ctx) ast_fully_specified_type();
$$->type->qualifier = $1.q; $$->type->qualifier = $1;
$$->type->specifier = $3; $$->type->specifier = $3;
} }
| parameter_qualifier parameter_type_specifier | parameter_qualifier parameter_type_specifier
@@ -787,7 +784,7 @@ parameter_declaration:
$$ = new(ctx) ast_parameter_declarator(); $$ = new(ctx) ast_parameter_declarator();
$$->set_location(yylloc); $$->set_location(yylloc);
$$->type = new(ctx) ast_fully_specified_type(); $$->type = new(ctx) ast_fully_specified_type();
$$->type->qualifier = $1.q; $$->type->qualifier = $1;
$$->type->specifier = $2; $$->type->specifier = $2;
} }
; ;
@@ -800,17 +797,18 @@ parameter_qualifier:
| IN_TOK | IN_TOK
{ {
memset(& $$, 0, sizeof($$)); memset(& $$, 0, sizeof($$));
$$.q.in = 1; $$.flags.q.in = 1;
} }
| OUT_TOK | OUT_TOK
{ {
memset(& $$, 0, sizeof($$)); memset(& $$, 0, sizeof($$));
$$.q.out = 1; $$.flags.q.out = 1;
} }
| INOUT_TOK | INOUT_TOK
{ {
memset(& $$, 0, sizeof($$)); memset(& $$, 0, sizeof($$));
$$.q.in = 1; $$.q.out = 1; $$.flags.q.in = 1;
$$.flags.q.out = 1;
} }
; ;
@@ -969,7 +967,7 @@ fully_specified_type:
void *ctx = state; void *ctx = state;
$$ = new(ctx) ast_fully_specified_type(); $$ = new(ctx) ast_fully_specified_type();
$$->set_location(yylloc); $$->set_location(yylloc);
$$->qualifier = $1.q; $$->qualifier = $1;
$$->specifier = $2; $$->specifier = $2;
} }
; ;
@@ -985,7 +983,10 @@ layout_qualifier_id_list:
layout_qualifier_id layout_qualifier_id
| layout_qualifier_id_list ',' layout_qualifier_id | layout_qualifier_id_list ',' layout_qualifier_id
{ {
$$.i = $1.i | $3.i; /* FINISHME: Should check for conflicting / duplicate flags here.
*/
$$ = $1;
$$.flags.i |= $3.flags.i;
} }
; ;
@@ -999,10 +1000,10 @@ layout_qualifier_id:
if (state->ARB_fragment_coord_conventions_enable) { if (state->ARB_fragment_coord_conventions_enable) {
if (strcmp($1, "origin_upper_left") == 0) { if (strcmp($1, "origin_upper_left") == 0) {
got_one = true; got_one = true;
$$.q.origin_upper_left = 1; $$.flags.q.origin_upper_left = 1;
} else if (strcmp($1, "pixel_center_integer") == 0) { } else if (strcmp($1, "pixel_center_integer") == 0) {
got_one = true; got_one = true;
$$.q.pixel_center_integer = 1; $$.flags.q.pixel_center_integer = 1;
} }
} }
@@ -1025,17 +1026,17 @@ interpolation_qualifier:
SMOOTH SMOOTH
{ {
memset(& $$, 0, sizeof($$)); memset(& $$, 0, sizeof($$));
$$.q.smooth = 1; $$.flags.q.smooth = 1;
} }
| FLAT | FLAT
{ {
memset(& $$, 0, sizeof($$)); memset(& $$, 0, sizeof($$));
$$.q.flat = 1; $$.flags.q.flat = 1;
} }
| NOPERSPECTIVE | NOPERSPECTIVE
{ {
memset(& $$, 0, sizeof($$)); memset(& $$, 0, sizeof($$));
$$.q.noperspective = 1; $$.flags.q.noperspective = 1;
} }
; ;
@@ -1043,7 +1044,7 @@ parameter_type_qualifier:
CONST_TOK CONST_TOK
{ {
memset(& $$, 0, sizeof($$)); memset(& $$, 0, sizeof($$));
$$.q.constant = 1; $$.flags.q.constant = 1;
} }
; ;
@@ -1052,27 +1053,30 @@ type_qualifier:
| layout_qualifier | layout_qualifier
| layout_qualifier storage_qualifier | layout_qualifier storage_qualifier
{ {
$$.i = $1.i | $2.i; $$ = $1;
$$.flags.i |= $2.flags.i;
} }
| interpolation_qualifier | interpolation_qualifier
| interpolation_qualifier storage_qualifier | interpolation_qualifier storage_qualifier
{ {
$$.i = $1.i | $2.i; $$ = $1;
$$.flags.i |= $2.flags.i;
} }
| INVARIANT storage_qualifier | INVARIANT storage_qualifier
{ {
$$ = $2; $$ = $2;
$$.q.invariant = 1; $$.flags.q.invariant = 1;
} }
| INVARIANT interpolation_qualifier storage_qualifier | INVARIANT interpolation_qualifier storage_qualifier
{ {
$$.i = $2.i | $3.i; $$ = $2;
$$.q.invariant = 1; $$.flags.i |= $3.flags.i;
$$.flags.q.invariant = 1;
} }
| INVARIANT | INVARIANT
{ {
memset(& $$, 0, sizeof($$)); memset(& $$, 0, sizeof($$));
$$.q.invariant = 1; $$.flags.q.invariant = 1;
} }
; ;
@@ -1080,47 +1084,48 @@ storage_qualifier:
CONST_TOK CONST_TOK
{ {
memset(& $$, 0, sizeof($$)); memset(& $$, 0, sizeof($$));
$$.q.constant = 1; $$.flags.q.constant = 1;
} }
| ATTRIBUTE | ATTRIBUTE
{ {
memset(& $$, 0, sizeof($$)); memset(& $$, 0, sizeof($$));
$$.q.attribute = 1; $$.flags.q.attribute = 1;
} }
| VARYING | VARYING
{ {
memset(& $$, 0, sizeof($$)); memset(& $$, 0, sizeof($$));
$$.q.varying = 1; $$.flags.q.varying = 1;
} }
| CENTROID VARYING | CENTROID VARYING
{ {
memset(& $$, 0, sizeof($$)); memset(& $$, 0, sizeof($$));
$$.q.centroid = 1; $$.q.varying = 1; $$.flags.q.centroid = 1;
$$.flags.q.varying = 1;
} }
| IN_TOK | IN_TOK
{ {
memset(& $$, 0, sizeof($$)); memset(& $$, 0, sizeof($$));
$$.q.in = 1; $$.flags.q.in = 1;
} }
| OUT_TOK | OUT_TOK
{ {
memset(& $$, 0, sizeof($$)); memset(& $$, 0, sizeof($$));
$$.q.out = 1; $$.flags.q.out = 1;
} }
| CENTROID IN_TOK | CENTROID IN_TOK
{ {
memset(& $$, 0, sizeof($$)); memset(& $$, 0, sizeof($$));
$$.q.centroid = 1; $$.q.in = 1; $$.flags.q.centroid = 1; $$.flags.q.in = 1;
} }
| CENTROID OUT_TOK | CENTROID OUT_TOK
{ {
memset(& $$, 0, sizeof($$)); memset(& $$, 0, sizeof($$));
$$.q.centroid = 1; $$.q.out = 1; $$.flags.q.centroid = 1; $$.flags.q.out = 1;
} }
| UNIFORM | UNIFORM
{ {
memset(& $$, 0, sizeof($$)); memset(& $$, 0, sizeof($$));
$$.q.uniform = 1; $$.flags.q.uniform = 1;
} }
; ;

View File

@@ -219,37 +219,37 @@ _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
void void
_mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q) _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
{ {
if (q->constant) if (q->flags.q.constant)
printf("const "); printf("const ");
if (q->invariant) if (q->flags.q.invariant)
printf("invariant "); printf("invariant ");
if (q->attribute) if (q->flags.q.attribute)
printf("attribute "); printf("attribute ");
if (q->varying) if (q->flags.q.varying)
printf("varying "); printf("varying ");
if (q->in && q->out) if (q->flags.q.in && q->flags.q.out)
printf("inout "); printf("inout ");
else { else {
if (q->in) if (q->flags.q.in)
printf("in "); printf("in ");
if (q->out) if (q->flags.q.out)
printf("out "); printf("out ");
} }
if (q->centroid) if (q->flags.q.centroid)
printf("centroid "); printf("centroid ");
if (q->uniform) if (q->flags.q.uniform)
printf("uniform "); printf("uniform ");
if (q->smooth) if (q->flags.q.smooth)
printf("smooth "); printf("smooth ");
if (q->flat) if (q->flags.q.flat)
printf("flat "); printf("flat ");
if (q->noperspective) if (q->flags.q.noperspective)
printf("noperspective "); printf("noperspective ");
} }