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,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);