* (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 PASTE
-%type <ival> INTEGER operator SPACE integer_constant
+%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 <string_list> identifier_list
| HASH_TOKEN ENDIF {
_glcpp_parser_skip_stack_pop (parser, & @1);
} NEWLINE
-| HASH_TOKEN VERSION_TOKEN integer_constant NEWLINE {
- if (parser->version != 0) {
+| HASH_TOKEN VERSION_TOKEN version_constant NEWLINE {
+ if (parser->version_set) {
glcpp_error(& @1, parser, "#version must appear on the first line");
}
_glcpp_parser_handle_version_declaration(parser, $3, NULL, true);
}
-| HASH_TOKEN VERSION_TOKEN integer_constant IDENTIFIER NEWLINE {
- if (parser->version != 0) {
+| HASH_TOKEN VERSION_TOKEN version_constant IDENTIFIER NEWLINE {
+ if (parser->version_set) {
glcpp_error(& @1, parser, "#version must appear on the first line");
}
_glcpp_parser_handle_version_declaration(parser, $3, $4, true);
$$ = $1;
}
+version_constant:
+ INTEGER_STRING {
+ /* Both octal and hexadecimal constants begin with 0. */
+ if ($1[0] == '0' && $1[1] != '\0') {
+ glcpp_error(&@1, parser, "invalid #version \"%s\" (not a decimal constant)", $1);
+ $$ = 0;
+ } else {
+ $$ = strtoll($1, NULL, 10);
+ }
+ }
+
expression:
integer_constant {
$$.value = $1;
parser->state = state;
parser->api = api;
parser->version = 0;
+ parser->version_set = false;
parser->has_new_line_number = 0;
parser->new_line_number = 1;
const char *es_identifier,
bool explicitly_set)
{
- if (parser->version != 0)
+ if (parser->version_set)
return;
parser->version = version;
+ parser->version_set = true;
add_builtin_define (parser, "__VERSION__", version);