* Add new field ast_type_specifier::is_precision_statement. * Add semantic checks in ast_type_specifier::hir(). * Alter parser rules accordingly.tags/android-x86-2.2-r2
@@ -462,7 +462,8 @@ public: | |||
/** Construct a type specifier from a type name */ | |||
ast_type_specifier(const char *name) | |||
: type_specifier(ast_type_name), type_name(name), structure(NULL), | |||
is_array(false), array_size(NULL), precision(ast_precision_none) | |||
is_array(false), array_size(NULL), precision(ast_precision_none), | |||
is_precision_statement(false) | |||
{ | |||
/* empty */ | |||
} | |||
@@ -470,7 +471,8 @@ public: | |||
/** Construct a type specifier from a structure definition */ | |||
ast_type_specifier(ast_struct_specifier *s) | |||
: type_specifier(ast_struct), type_name(s->name), structure(s), | |||
is_array(false), array_size(NULL), precision(ast_precision_none) | |||
is_array(false), array_size(NULL), precision(ast_precision_none), | |||
is_precision_statement(false) | |||
{ | |||
/* empty */ | |||
} | |||
@@ -492,6 +494,8 @@ public: | |||
ast_expression *array_size; | |||
unsigned precision:2; | |||
bool is_precision_statement; | |||
}; | |||
@@ -3239,6 +3239,58 @@ ir_rvalue * | |||
ast_type_specifier::hir(exec_list *instructions, | |||
struct _mesa_glsl_parse_state *state) | |||
{ | |||
if (!this->is_precision_statement && this->structure == NULL) | |||
return NULL; | |||
YYLTYPE loc = this->get_location(); | |||
if (this->precision != ast_precision_none | |||
&& state->language_version != 100 | |||
&& state->language_version < 130) { | |||
_mesa_glsl_error(&loc, state, | |||
"precision qualifiers exist only in " | |||
"GLSL ES 1.00, and GLSL 1.30 and later"); | |||
return NULL; | |||
} | |||
if (this->precision != ast_precision_none | |||
&& this->structure != NULL) { | |||
_mesa_glsl_error(&loc, state, | |||
"precision qualifiers do not apply to structures"); | |||
return NULL; | |||
} | |||
/* If this is a precision statement, check that the type to which it is | |||
* applied is either float or int. | |||
* | |||
* From section 4.5.3 of the GLSL 1.30 spec: | |||
* "The precision statement | |||
* precision precision-qualifier type; | |||
* can be used to establish a default precision qualifier. The type | |||
* field can be either int or float [...]. Any other types or | |||
* qualifiers will result in an error. | |||
*/ | |||
if (this->is_precision_statement) { | |||
assert(this->precision != ast_precision_none); | |||
assert(this->structure == NULL); /* The check for structures was | |||
* performed above. */ | |||
if (this->is_array) { | |||
_mesa_glsl_error(&loc, state, | |||
"default precision statements do not apply to " | |||
"arrays"); | |||
return NULL; | |||
} | |||
if (this->type_specifier != ast_float | |||
&& this->type_specifier != ast_int) { | |||
_mesa_glsl_error(&loc, state, | |||
"default precision statements apply only to types " | |||
"float and int"); | |||
return NULL; | |||
} | |||
/* FINISHME: Translate precision statements into IR. */ | |||
return NULL; | |||
} | |||
if (this->structure != NULL) | |||
return this->structure->hir(instructions, state); | |||
@@ -49,7 +49,8 @@ ast_type_specifier::print(void) const | |||
ast_type_specifier::ast_type_specifier(int specifier) | |||
: type_specifier(ast_types(specifier)), type_name(NULL), structure(NULL), | |||
is_array(false), array_size(NULL), precision(ast_precision_none) | |||
is_array(false), array_size(NULL), precision(ast_precision_none), | |||
is_precision_statement(false) | |||
{ | |||
static const char *const names[] = { | |||
"void", |
@@ -276,16 +276,16 @@ extension_statement: | |||
external_declaration_list: | |||
external_declaration | |||
{ | |||
/* FINISHME: The NULL test is only required because 'precision' | |||
* FINISHME: statements are not yet supported. | |||
/* FINISHME: The NULL test is required because pragmas are set to | |||
* FINISHME: NULL. (See production rule for external_declaration.) | |||
*/ | |||
if ($1 != NULL) | |||
state->translation_unit.push_tail(& $1->link); | |||
} | |||
| external_declaration_list external_declaration | |||
{ | |||
/* FINISHME: The NULL test is only required because 'precision' | |||
* FINISHME: statements are not yet supported. | |||
/* FINISHME: The NULL test is required because pragmas are set to | |||
* FINISHME: NULL. (See production rule for external_declaration.) | |||
*/ | |||
if ($2 != NULL) | |||
state->translation_unit.push_tail(& $2->link); | |||
@@ -708,8 +708,9 @@ declaration: | |||
"only be applied to `int' or `float'\n"); | |||
YYERROR; | |||
} | |||
$$ = NULL; /* FINISHME */ | |||
$3->precision = $2; | |||
$3->is_precision_statement = true; | |||
$$ = $3; | |||
} | |||
; | |||