cppparser: Parse nonstandard specifier order like "const static"

This commit is contained in:
rdb 2016-08-09 01:19:35 +02:00
parent 339eb58007
commit db97747981
5 changed files with 3703 additions and 4242 deletions

View File

@ -27,6 +27,7 @@ This issue fixes several bugs that were still found in 1.9.2.
* Support uint8 index buffers in DX9 * Support uint8 index buffers in DX9
* Fix occasional frame lag when loading a big model asynchronously * Fix occasional frame lag when loading a big model asynchronously
* Fix race condition reading string config var * Fix race condition reading string config var
* Fix interrogate parsing issue with "const static"
------------------------ RELEASE 1.9.2 ------------------------ ------------------------ RELEASE 1.9.2 ------------------------

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 2.7. */ /* A Bison parser, made by GNU Bison 3.0.4. */
/* Bison interface for Yacc-like parsers in C /* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -32,7 +32,7 @@
#ifndef YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED #ifndef YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED
# define YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED # define YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED
/* Enabling traces. */ /* Debug traces. */
#ifndef YYDEBUG #ifndef YYDEBUG
# define YYDEBUG 0 # define YYDEBUG 0
#endif #endif
@ -40,12 +40,11 @@
extern int cppyydebug; extern int cppyydebug;
#endif #endif
/* Tokens. */ /* Token type. */
#ifndef YYTOKENTYPE #ifndef YYTOKENTYPE
# define YYTOKENTYPE # define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers enum yytokentype
know about them. */ {
enum yytokentype {
REAL = 258, REAL = 258,
INTEGER = 259, INTEGER = 259,
CHAR_TOK = 260, CHAR_TOK = 260,
@ -258,40 +257,24 @@ extern int cppyydebug;
#define START_CONST_EXPR 360 #define START_CONST_EXPR 360
#define START_TYPE 361 #define START_TYPE 361
/* Value type. */
/* Location type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
typedef struct YYLTYPE typedef struct YYLTYPE YYLTYPE;
struct YYLTYPE
{ {
int first_line; int first_line;
int first_column; int first_column;
int last_line; int last_line;
int last_column; int last_column;
} YYLTYPE; };
# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
# define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_DECLARED 1
# define YYLTYPE_IS_TRIVIAL 1 # define YYLTYPE_IS_TRIVIAL 1
#endif #endif
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
int cppyyparse (void *YYPARSE_PARAM);
#else
int cppyyparse ();
#endif
#else /* ! YYPARSE_PARAM */
#if defined __STDC__ || defined __cplusplus
int cppyyparse (void); int cppyyparse (void);
#else
int cppyyparse ();
#endif
#endif /* ! YYPARSE_PARAM */
#endif /* !YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED */ #endif /* !YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED */

View File

@ -537,6 +537,11 @@ storage_class:
empty empty
{ {
$$ = 0; $$ = 0;
}
| storage_class KW_CONST
{
// This isn't really a storage class, but it helps with parsing.
$$ = $1 | (int)CPPInstance::SC_const;
} }
| storage_class KW_EXTERN | storage_class KW_EXTERN
{ {
@ -592,9 +597,20 @@ storage_class:
; ;
type_like_declaration: type_like_declaration:
multiple_var_declaration storage_class type_decl
{ {
/* multiple_var_declaration adds itself to the scope. */ // We don't need to push/pop type, because we can't nest
// multiple_var_declarations.
if ($2->as_type_declaration()) {
current_type = $2->as_type_declaration()->_type;
} else {
current_type = $2->as_type();
}
push_storage_class($1);
}
multiple_instance_identifiers
{
pop_storage_class();
} }
| storage_class type_decl ';' | storage_class type_decl ';'
{ {
@ -613,36 +629,6 @@ type_like_declaration:
$2->set_initializer($3); $2->set_initializer($3);
} }
} }
;
multiple_var_declaration:
storage_class type_decl
{
// We don't need to push/pop type, because we can't nest
// multiple_var_declarations.
if ($2->as_type_declaration()) {
current_type = $2->as_type_declaration()->_type;
} else {
current_type = $2->as_type();
}
push_storage_class($1);
}
multiple_instance_identifiers
{
pop_storage_class();
}
| storage_class KW_CONST type
{
// We don't need to push/pop type, because we can't nest
// multiple_var_declarations.
current_type = $3;
push_storage_class($1);
}
multiple_const_instance_identifiers
{
pop_storage_class();
}
/* We don't need to include a rule for variables that point to /* We don't need to include a rule for variables that point to
functions, because we get those from the function_prototype functions, because we get those from the function_prototype
definition. */ definition. */
@ -651,6 +637,9 @@ multiple_var_declaration:
multiple_instance_identifiers: multiple_instance_identifiers:
instance_identifier maybe_initialize_or_function_body instance_identifier maybe_initialize_or_function_body
{ {
if (current_storage_class & CPPInstance::SC_const) {
$1->add_modifier(IIT_const);
}
CPPInstance *inst = new CPPInstance(current_type, $1, CPPInstance *inst = new CPPInstance(current_type, $1,
current_storage_class, current_storage_class,
@1.file); @1.file);
@ -659,6 +648,9 @@ multiple_instance_identifiers:
} }
| instance_identifier maybe_initialize ',' multiple_instance_identifiers | instance_identifier maybe_initialize ',' multiple_instance_identifiers
{ {
if (current_storage_class & CPPInstance::SC_const) {
$1->add_modifier(IIT_const);
}
CPPInstance *inst = new CPPInstance(current_type, $1, CPPInstance *inst = new CPPInstance(current_type, $1,
current_storage_class, current_storage_class,
@1.file); @1.file);
@ -667,28 +659,6 @@ multiple_instance_identifiers:
} }
; ;
multiple_const_instance_identifiers:
instance_identifier maybe_initialize_or_function_body
{
$1->add_modifier(IIT_const);
CPPInstance *inst = new CPPInstance(current_type, $1,
current_storage_class,
@1.file);
inst->set_initializer($2);
current_scope->add_declaration(inst, global_scope, current_lexer, @1);
}
| instance_identifier maybe_initialize ',' multiple_const_instance_identifiers
{
$1->add_modifier(IIT_const);
CPPInstance *inst = new CPPInstance(current_type, $1,
current_storage_class,
@1.file);
inst->set_initializer($2);
current_scope->add_declaration(inst, global_scope, current_lexer, @1);
}
;
typedef_declaration: typedef_declaration:
storage_class type_decl storage_class type_decl
{ {
@ -704,17 +674,6 @@ typedef_declaration:
typedef_instance_identifiers typedef_instance_identifiers
{ {
pop_storage_class(); pop_storage_class();
}
| storage_class KW_CONST type
{
// We don't need to push/pop type, because we can't nest
// multiple_var_declarations.
current_type = $3;
push_storage_class($1);
}
typedef_const_instance_identifiers
{
pop_storage_class();
} }
| storage_class function_prototype maybe_initialize_or_function_body | storage_class function_prototype maybe_initialize_or_function_body
{ {
@ -733,29 +692,18 @@ typedef_declaration:
typedef_instance_identifiers: typedef_instance_identifiers:
instance_identifier maybe_initialize_or_function_body instance_identifier maybe_initialize_or_function_body
{ {
if (current_storage_class & CPPInstance::SC_const) {
$1->add_modifier(IIT_const);
}
CPPType *target_type = current_type; CPPType *target_type = current_type;
CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file); CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
current_scope->add_declaration(typedef_type, global_scope, current_lexer, @1); current_scope->add_declaration(typedef_type, global_scope, current_lexer, @1);
} }
| instance_identifier maybe_initialize ',' typedef_instance_identifiers | instance_identifier maybe_initialize ',' typedef_instance_identifiers
{ {
CPPType *target_type = current_type; if (current_storage_class & CPPInstance::SC_const) {
CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
current_scope->add_declaration(typedef_type, global_scope, current_lexer, @1);
}
;
typedef_const_instance_identifiers:
instance_identifier maybe_initialize_or_function_body
{
$1->add_modifier(IIT_const);
CPPType *target_type = current_type;
CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
current_scope->add_declaration(typedef_type, global_scope, current_lexer, @1);
}
| instance_identifier maybe_initialize ',' typedef_const_instance_identifiers
{
$1->add_modifier(IIT_const); $1->add_modifier(IIT_const);
}
CPPType *target_type = current_type; CPPType *target_type = current_type;
CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file); CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
current_scope->add_declaration(typedef_type, global_scope, current_lexer, @1); current_scope->add_declaration(typedef_type, global_scope, current_lexer, @1);

View File

@ -60,6 +60,10 @@ public:
// And this is for methods tagged with __extension, which declares // And this is for methods tagged with __extension, which declares
// extension methods defined separately from the source code. // extension methods defined separately from the source code.
SC_extension = 0x1000, SC_extension = 0x1000,
// This isn't really a storage class. It's only used temporarily by the
// parser, to make parsing specifier sequences a bit easier.
SC_const = 0x20000,
}; };
CPPInstance(CPPType *type, const string &name, int storage_class = 0); CPPInstance(CPPType *type, const string &name, int storage_class = 0);