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,19 +1,19 @@
/* 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
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */ along with this program. If not, see <http://www.gnu.org/licenses/>. */
@ -26,13 +26,13 @@
special exception, which will cause the skeleton and the resulting special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public Bison output files to be licensed under the GNU General Public
License without this special exception. License without this special exception.
This special exception was added by the Free Software Foundation in This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */ version 2.2 of Bison. */
#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,117 +40,116 @@
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, STRING = 261,
STRING = 261, SIMPLE_IDENTIFIER = 262,
SIMPLE_IDENTIFIER = 262, IDENTIFIER = 263,
IDENTIFIER = 263, TYPENAME_IDENTIFIER = 264,
TYPENAME_IDENTIFIER = 264, SCOPING = 265,
SCOPING = 265, TYPEDEFNAME = 266,
TYPEDEFNAME = 266, ELLIPSIS = 267,
ELLIPSIS = 267, OROR = 268,
OROR = 268, ANDAND = 269,
ANDAND = 269, EQCOMPARE = 270,
EQCOMPARE = 270, NECOMPARE = 271,
NECOMPARE = 271, LECOMPARE = 272,
LECOMPARE = 272, GECOMPARE = 273,
GECOMPARE = 273, LSHIFT = 274,
LSHIFT = 274, RSHIFT = 275,
RSHIFT = 275, POINTSAT_STAR = 276,
POINTSAT_STAR = 276, DOT_STAR = 277,
DOT_STAR = 277, UNARY = 278,
UNARY = 278, UNARY_NOT = 279,
UNARY_NOT = 279, UNARY_NEGATE = 280,
UNARY_NEGATE = 280, UNARY_MINUS = 281,
UNARY_MINUS = 281, UNARY_STAR = 282,
UNARY_STAR = 282, UNARY_REF = 283,
UNARY_REF = 283, POINTSAT = 284,
POINTSAT = 284, SCOPE = 285,
SCOPE = 285, PLUSPLUS = 286,
PLUSPLUS = 286, MINUSMINUS = 287,
MINUSMINUS = 287, TIMESEQUAL = 288,
TIMESEQUAL = 288, DIVIDEEQUAL = 289,
DIVIDEEQUAL = 289, MODEQUAL = 290,
MODEQUAL = 290, PLUSEQUAL = 291,
PLUSEQUAL = 291, MINUSEQUAL = 292,
MINUSEQUAL = 292, OREQUAL = 293,
OREQUAL = 293, ANDEQUAL = 294,
ANDEQUAL = 294, XOREQUAL = 295,
XOREQUAL = 295, LSHIFTEQUAL = 296,
LSHIFTEQUAL = 296, RSHIFTEQUAL = 297,
RSHIFTEQUAL = 297, KW_BEGIN_PUBLISH = 298,
KW_BEGIN_PUBLISH = 298, KW_BLOCKING = 299,
KW_BLOCKING = 299, KW_BOOL = 300,
KW_BOOL = 300, KW_CATCH = 301,
KW_CATCH = 301, KW_CHAR = 302,
KW_CHAR = 302, KW_CHAR16_T = 303,
KW_CHAR16_T = 303, KW_CHAR32_T = 304,
KW_CHAR32_T = 304, KW_CLASS = 305,
KW_CLASS = 305, KW_CONST = 306,
KW_CONST = 306, KW_DELETE = 307,
KW_DELETE = 307, KW_DOUBLE = 308,
KW_DOUBLE = 308, KW_DYNAMIC_CAST = 309,
KW_DYNAMIC_CAST = 309, KW_ELSE = 310,
KW_ELSE = 310, KW_END_PUBLISH = 311,
KW_END_PUBLISH = 311, KW_ENUM = 312,
KW_ENUM = 312, KW_EXTENSION = 313,
KW_EXTENSION = 313, KW_EXTERN = 314,
KW_EXTERN = 314, KW_EXPLICIT = 315,
KW_EXPLICIT = 315, KW_PUBLISHED = 316,
KW_PUBLISHED = 316, KW_FALSE = 317,
KW_FALSE = 317, KW_FLOAT = 318,
KW_FLOAT = 318, KW_FRIEND = 319,
KW_FRIEND = 319, KW_FOR = 320,
KW_FOR = 320, KW_GOTO = 321,
KW_GOTO = 321, KW_IF = 322,
KW_IF = 322, KW_INLINE = 323,
KW_INLINE = 323, KW_INT = 324,
KW_INT = 324, KW_LONG = 325,
KW_LONG = 325, KW_LONGLONG = 326,
KW_LONGLONG = 326, KW_MAKE_PROPERTY = 327,
KW_MAKE_PROPERTY = 327, KW_MAKE_SEQ = 328,
KW_MAKE_SEQ = 328, KW_MUTABLE = 329,
KW_MUTABLE = 329, KW_NAMESPACE = 330,
KW_NAMESPACE = 330, KW_NEW = 331,
KW_NEW = 331, KW_NOEXCEPT = 332,
KW_NOEXCEPT = 332, KW_OPERATOR = 333,
KW_OPERATOR = 333, KW_PRIVATE = 334,
KW_PRIVATE = 334, KW_PROTECTED = 335,
KW_PROTECTED = 335, KW_PUBLIC = 336,
KW_PUBLIC = 336, KW_REGISTER = 337,
KW_REGISTER = 337, KW_RETURN = 338,
KW_RETURN = 338, KW_SHORT = 339,
KW_SHORT = 339, KW_SIGNED = 340,
KW_SIGNED = 340, KW_SIZEOF = 341,
KW_SIZEOF = 341, KW_STATIC = 342,
KW_STATIC = 342, KW_STATIC_CAST = 343,
KW_STATIC_CAST = 343, KW_STRUCT = 344,
KW_STRUCT = 344, KW_TEMPLATE = 345,
KW_TEMPLATE = 345, KW_THROW = 346,
KW_THROW = 346, KW_TRUE = 347,
KW_TRUE = 347, KW_TRY = 348,
KW_TRY = 348, KW_TYPEDEF = 349,
KW_TYPEDEF = 349, KW_TYPENAME = 350,
KW_TYPENAME = 350, KW_UNION = 351,
KW_UNION = 351, KW_UNSIGNED = 352,
KW_UNSIGNED = 352, KW_USING = 353,
KW_USING = 353, KW_VIRTUAL = 354,
KW_VIRTUAL = 354, KW_VOID = 355,
KW_VOID = 355, KW_VOLATILE = 356,
KW_VOLATILE = 356, KW_WCHAR_T = 357,
KW_WCHAR_T = 357, KW_WHILE = 358,
KW_WHILE = 358, START_CPP = 359,
START_CPP = 359, START_CONST_EXPR = 360,
START_CONST_EXPR = 360, START_TYPE = 361
START_TYPE = 361 };
};
#endif #endif
/* Tokens. */ /* Tokens. */
#define REAL 258 #define REAL 258
@ -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); $1->add_modifier(IIT_const);
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);
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);