|
|
@@ -212,7 +212,7 @@ pop_struct() {
|
|
|
%token <u.integer> CHAR_TOK
|
|
|
%token <str> SIMPLE_STRING SIMPLE_IDENTIFIER
|
|
|
%token <u.expr> STRING_LITERAL CUSTOM_LITERAL
|
|
|
-%token <u.identifier> IDENTIFIER TYPENAME_IDENTIFIER SCOPING
|
|
|
+%token <u.identifier> IDENTIFIER TYPENAME_IDENTIFIER TYPEPACK_IDENTIFIER SCOPING
|
|
|
%token <u.type> TYPEDEFNAME
|
|
|
|
|
|
%token ELLIPSIS
|
|
|
@@ -280,9 +280,25 @@ pop_struct() {
|
|
|
%token KW_FRIEND
|
|
|
%token KW_FOR
|
|
|
%token KW_GOTO
|
|
|
+%token KW_HAS_VIRTUAL_DESTRUCTOR
|
|
|
%token KW_IF
|
|
|
%token KW_INLINE
|
|
|
%token KW_INT
|
|
|
+%token KW_IS_ABSTRACT
|
|
|
+%token KW_IS_BASE_OF
|
|
|
+%token KW_IS_CLASS
|
|
|
+%token KW_IS_CONSTRUCTIBLE
|
|
|
+%token KW_IS_CONVERTIBLE_TO
|
|
|
+%token KW_IS_DESTRUCTIBLE
|
|
|
+%token KW_IS_EMPTY
|
|
|
+%token KW_IS_ENUM
|
|
|
+%token KW_IS_FINAL
|
|
|
+%token KW_IS_FUNDAMENTAL
|
|
|
+%token KW_IS_POD
|
|
|
+%token KW_IS_POLYMORPHIC
|
|
|
+%token KW_IS_STANDARD_LAYOUT
|
|
|
+%token KW_IS_TRIVIAL
|
|
|
+%token KW_IS_UNION
|
|
|
%token KW_LONG
|
|
|
%token KW_MAKE_MAP_PROPERTY
|
|
|
%token KW_MAKE_PROPERTY
|
|
|
@@ -317,6 +333,7 @@ pop_struct() {
|
|
|
%token KW_TYPEDEF
|
|
|
%token KW_TYPEID
|
|
|
%token KW_TYPENAME
|
|
|
+%token KW_UNDERLYING_TYPE
|
|
|
%token KW_UNION
|
|
|
%token KW_UNSIGNED
|
|
|
%token KW_USING
|
|
|
@@ -354,9 +371,10 @@ pop_struct() {
|
|
|
%type <u.instance> formal_parameter
|
|
|
%type <u.inst_ident> not_paren_formal_parameter_identifier
|
|
|
%type <u.inst_ident> formal_parameter_identifier
|
|
|
+%type <u.inst_ident> parameter_pack_identifier
|
|
|
%type <u.inst_ident> not_paren_empty_instance_identifier
|
|
|
%type <u.inst_ident> empty_instance_identifier
|
|
|
-%type <u.type> type
|
|
|
+%type <u.type> type type_pack
|
|
|
%type <u.decl> type_decl
|
|
|
%type <u.decl> var_type_decl
|
|
|
%type <u.type> predefined_type
|
|
|
@@ -447,6 +465,10 @@ constructor_init:
|
|
|
name '(' optional_const_expr_comma ')'
|
|
|
{
|
|
|
delete $3;
|
|
|
+}
|
|
|
+ | name '(' optional_const_expr_comma ')' ELLIPSIS
|
|
|
+{
|
|
|
+ delete $3;
|
|
|
}
|
|
|
| name '{' optional_const_expr_comma '}'
|
|
|
{
|
|
|
@@ -783,6 +805,11 @@ storage_class:
|
|
|
empty
|
|
|
{
|
|
|
$$ = 0;
|
|
|
+}
|
|
|
+ | KW_CONST storage_class
|
|
|
+{
|
|
|
+ // This isn't really a storage class, but it helps with parsing.
|
|
|
+ $$ = $2 | (int)CPPInstance::SC_const;
|
|
|
}
|
|
|
| KW_EXTERN storage_class
|
|
|
{
|
|
|
@@ -861,10 +888,22 @@ attribute_specifier:
|
|
|
;
|
|
|
|
|
|
type_like_declaration:
|
|
|
- multiple_var_declaration
|
|
|
+ storage_class var_type_decl
|
|
|
+{
|
|
|
+ // We don't need to push/pop type, because we can't nest
|
|
|
+ // type_like_declaration.
|
|
|
+ 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
|
|
|
{
|
|
|
- /* multiple_var_declaration adds itself to the scope. */
|
|
|
+ pop_storage_class();
|
|
|
}
|
|
|
+
|
|
|
| storage_class type_decl ';'
|
|
|
{
|
|
|
// We don't really care about the storage class here. In fact, it's
|
|
|
@@ -891,39 +930,6 @@ type_like_declaration:
|
|
|
}
|
|
|
}
|
|
|
| using_declaration
|
|
|
- ;
|
|
|
-
|
|
|
-multiple_var_declaration:
|
|
|
- storage_class var_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 var_type_decl
|
|
|
-{
|
|
|
- // We don't need to push/pop type, because we can't nest
|
|
|
- // multiple_var_declarations.
|
|
|
- if ($3->as_type_declaration()) {
|
|
|
- current_type = $3->as_type_declaration()->_type;
|
|
|
- } else {
|
|
|
- current_type = $3->as_type();
|
|
|
- }
|
|
|
- push_storage_class($1);
|
|
|
-}
|
|
|
- multiple_const_instance_identifiers
|
|
|
-{
|
|
|
- pop_storage_class();
|
|
|
-}
|
|
|
|
|
|
/* We don't need to include a rule for variables that point to
|
|
|
functions, because we get those from the function_prototype
|
|
|
@@ -933,6 +939,9 @@ multiple_var_declaration:
|
|
|
multiple_instance_identifiers:
|
|
|
instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
|
|
|
{
|
|
|
+ if (current_storage_class & CPPInstance::SC_const) {
|
|
|
+ $1->add_modifier(IIT_const);
|
|
|
+ }
|
|
|
CPPInstance *inst = new CPPInstance(current_type, $1,
|
|
|
current_storage_class,
|
|
|
@1.file);
|
|
|
@@ -941,27 +950,9 @@ multiple_instance_identifiers:
|
|
|
}
|
|
|
| instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' multiple_instance_identifiers
|
|
|
{
|
|
|
- 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);
|
|
|
-}
|
|
|
- ;
|
|
|
-
|
|
|
-multiple_const_instance_identifiers:
|
|
|
- instance_identifier_and_maybe_trailing_return_type 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_and_maybe_trailing_return_type maybe_initialize ',' multiple_const_instance_identifiers
|
|
|
-{
|
|
|
- $1->add_modifier(IIT_const);
|
|
|
+ if (current_storage_class & CPPInstance::SC_const) {
|
|
|
+ $1->add_modifier(IIT_const);
|
|
|
+ }
|
|
|
CPPInstance *inst = new CPPInstance(current_type, $1,
|
|
|
current_storage_class,
|
|
|
@1.file);
|
|
|
@@ -986,21 +977,6 @@ typedef_declaration:
|
|
|
typedef_instance_identifiers
|
|
|
{
|
|
|
pop_storage_class();
|
|
|
-}
|
|
|
- | storage_class KW_CONST var_type_decl
|
|
|
-{
|
|
|
- // We don't need to push/pop type, because we can't nest
|
|
|
- // multiple_var_declarations.
|
|
|
- if ($3->as_type_declaration()) {
|
|
|
- current_type = $3->as_type_declaration()->_type;
|
|
|
- } else {
|
|
|
- current_type = $3->as_type();
|
|
|
- }
|
|
|
- push_storage_class($1);
|
|
|
-}
|
|
|
- typedef_const_instance_identifiers
|
|
|
-{
|
|
|
- pop_storage_class();
|
|
|
}
|
|
|
| storage_class function_prototype maybe_initialize_or_function_body
|
|
|
{
|
|
|
@@ -1019,29 +995,18 @@ typedef_declaration:
|
|
|
typedef_instance_identifiers:
|
|
|
instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
|
|
|
{
|
|
|
+ if (current_storage_class & CPPInstance::SC_const) {
|
|
|
+ $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(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);
|
|
|
}
|
|
|
| instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' typedef_instance_identifiers
|
|
|
{
|
|
|
- CPPType *target_type = current_type;
|
|
|
- CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
|
|
|
- current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);
|
|
|
-}
|
|
|
- ;
|
|
|
-
|
|
|
-typedef_const_instance_identifiers:
|
|
|
- instance_identifier_and_maybe_trailing_return_type 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(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);
|
|
|
-}
|
|
|
- | instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' typedef_const_instance_identifiers
|
|
|
-{
|
|
|
- $1->add_modifier(IIT_const);
|
|
|
+ if (current_storage_class & CPPInstance::SC_const) {
|
|
|
+ $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(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);
|
|
|
@@ -1244,26 +1209,38 @@ function_post:
|
|
|
{
|
|
|
$$ = 0;
|
|
|
}
|
|
|
- | KW_CONST
|
|
|
+ | function_post KW_CONST
|
|
|
+{
|
|
|
+ $$ = $1 | (int)CPPFunctionType::F_const_method;
|
|
|
+}
|
|
|
+ | function_post KW_VOLATILE
|
|
|
{
|
|
|
- $$ = (int)CPPFunctionType::F_const_method;
|
|
|
+ $$ = $1 | (int)CPPFunctionType::F_volatile_method;
|
|
|
}
|
|
|
| function_post KW_NOEXCEPT
|
|
|
{
|
|
|
- $$ = (int)CPPFunctionType::F_noexcept;
|
|
|
+ $$ = $1 | (int)CPPFunctionType::F_noexcept;
|
|
|
}
|
|
|
| function_post KW_FINAL
|
|
|
{
|
|
|
- $$ = (int)CPPFunctionType::F_final;
|
|
|
+ $$ = $1 | (int)CPPFunctionType::F_final;
|
|
|
}
|
|
|
| function_post KW_OVERRIDE
|
|
|
{
|
|
|
- $$ = (int)CPPFunctionType::F_override;
|
|
|
+ $$ = $1 | (int)CPPFunctionType::F_override;
|
|
|
+}
|
|
|
+ | function_post '&'
|
|
|
+{
|
|
|
+ $$ = $1 | (int)CPPFunctionType::F_lvalue_method;
|
|
|
+}
|
|
|
+ | function_post ANDAND
|
|
|
+{
|
|
|
+ $$ = $1 | (int)CPPFunctionType::F_rvalue_method;
|
|
|
}
|
|
|
| function_post KW_MUTABLE
|
|
|
{
|
|
|
// Used for lambdas, currently ignored.
|
|
|
- $$ = 0;
|
|
|
+ $$ = $1;
|
|
|
}
|
|
|
| function_post KW_THROW '(' ')'
|
|
|
{
|
|
|
@@ -1272,6 +1249,10 @@ function_post:
|
|
|
| function_post KW_THROW '(' name ')'
|
|
|
{
|
|
|
$$ = $1;
|
|
|
+}
|
|
|
+ | function_post KW_THROW '(' name ELLIPSIS ')'
|
|
|
+{
|
|
|
+ $$ = $1;
|
|
|
}
|
|
|
/* | function_post '[' '[' attribute_specifiers ']' ']'
|
|
|
{
|
|
|
@@ -1475,22 +1456,35 @@ template_nonempty_formal_parameters:
|
|
|
}
|
|
|
;
|
|
|
|
|
|
+typename_keyword:
|
|
|
+ KW_CLASS
|
|
|
+ | KW_TYPENAME
|
|
|
+ ;
|
|
|
+
|
|
|
template_formal_parameter:
|
|
|
- KW_CLASS name
|
|
|
+ typename_keyword
|
|
|
+{
|
|
|
+ $$ = CPPType::new_type(new CPPClassTemplateParameter((CPPIdentifier *)NULL));
|
|
|
+}
|
|
|
+ | typename_keyword name
|
|
|
{
|
|
|
$$ = CPPType::new_type(new CPPClassTemplateParameter($2));
|
|
|
}
|
|
|
- | KW_CLASS name '=' full_type
|
|
|
+ | typename_keyword name '=' full_type
|
|
|
{
|
|
|
$$ = CPPType::new_type(new CPPClassTemplateParameter($2, $4));
|
|
|
}
|
|
|
- | KW_TYPENAME name
|
|
|
+ | typename_keyword ELLIPSIS
|
|
|
{
|
|
|
- $$ = CPPType::new_type(new CPPClassTemplateParameter($2));
|
|
|
+ CPPClassTemplateParameter *ctp = new CPPClassTemplateParameter((CPPIdentifier *)NULL);
|
|
|
+ ctp->_packed = true;
|
|
|
+ $$ = CPPType::new_type(ctp);
|
|
|
}
|
|
|
- | KW_TYPENAME name '=' full_type
|
|
|
+ | typename_keyword ELLIPSIS name
|
|
|
{
|
|
|
- $$ = CPPType::new_type(new CPPClassTemplateParameter($2, $4));
|
|
|
+ CPPClassTemplateParameter *ctp = new CPPClassTemplateParameter($3);
|
|
|
+ ctp->_packed = true;
|
|
|
+ $$ = CPPType::new_type(ctp);
|
|
|
}
|
|
|
| template_formal_parameter_type formal_parameter_identifier template_parameter_maybe_initialize
|
|
|
{
|
|
|
@@ -1504,6 +1498,17 @@ template_formal_parameter:
|
|
|
CPPInstance *inst = new CPPInstance($2, $3, 0, @3.file);
|
|
|
inst->set_initializer($4);
|
|
|
$$ = inst;
|
|
|
+}
|
|
|
+ | template_formal_parameter_type parameter_pack_identifier
|
|
|
+{
|
|
|
+ CPPInstance *inst = new CPPInstance($1, $2, 0, @2.file);
|
|
|
+ $$ = inst;
|
|
|
+}
|
|
|
+ | KW_CONST template_formal_parameter_type parameter_pack_identifier
|
|
|
+{
|
|
|
+ $3->add_modifier(IIT_const);
|
|
|
+ CPPInstance *inst = new CPPInstance($2, $3, 0, @3.file);
|
|
|
+ $$ = inst;
|
|
|
}
|
|
|
;
|
|
|
|
|
|
@@ -1524,6 +1529,14 @@ template_formal_parameter_type:
|
|
|
yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
|
|
|
}
|
|
|
assert($$ != NULL);
|
|
|
+}
|
|
|
+ | TYPEPACK_IDENTIFIER
|
|
|
+{
|
|
|
+ $$ = $1->find_type(current_scope, global_scope, false, current_lexer);
|
|
|
+ if ($$ == NULL) {
|
|
|
+ yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
|
|
|
+ }
|
|
|
+ assert($$ != NULL);
|
|
|
}
|
|
|
;
|
|
|
|
|
|
@@ -1604,7 +1617,16 @@ instance_identifier:
|
|
|
}
|
|
|
| instance_identifier '('
|
|
|
{
|
|
|
- push_scope($1->get_scope(current_scope, global_scope));
|
|
|
+ // Create a scope for this function (in case it is a function)
|
|
|
+ CPPScope *scope = new CPPScope($1->get_scope(current_scope, global_scope),
|
|
|
+ CPPNameComponent(""), V_private);
|
|
|
+
|
|
|
+ // It still needs to be able to pick up any template arguments, if this is
|
|
|
+ // a definition for a method template. Add a fake "using" declaration to
|
|
|
+ // accomplish this.
|
|
|
+ scope->_using.insert(current_scope);
|
|
|
+
|
|
|
+ push_scope(scope);
|
|
|
}
|
|
|
formal_parameter_list ')' function_post
|
|
|
{
|
|
|
@@ -1842,6 +1864,23 @@ function_parameter:
|
|
|
$4->add_modifier(IIT_const);
|
|
|
$$ = new CPPInstance($3, $4, 0, @3.file);
|
|
|
$$->set_initializer($5);
|
|
|
+}
|
|
|
+ | type_pack parameter_pack_identifier maybe_initialize
|
|
|
+{
|
|
|
+ $$ = new CPPInstance($1, $2, 0, @2.file);
|
|
|
+ $$->set_initializer($3);
|
|
|
+}
|
|
|
+ | KW_CONST type_pack parameter_pack_identifier maybe_initialize
|
|
|
+{
|
|
|
+ $3->add_modifier(IIT_const);
|
|
|
+ $$ = new CPPInstance($2, $3, 0, @3.file);
|
|
|
+ $$->set_initializer($4);
|
|
|
+}
|
|
|
+ | KW_CONST KW_REGISTER type_pack parameter_pack_identifier maybe_initialize
|
|
|
+{
|
|
|
+ $4->add_modifier(IIT_const);
|
|
|
+ $$ = new CPPInstance($3, $4, 0, @3.file);
|
|
|
+ $$->set_initializer($5);
|
|
|
}
|
|
|
| KW_REGISTER function_parameter
|
|
|
{
|
|
|
@@ -1970,10 +2009,79 @@ formal_parameter_identifier:
|
|
|
}
|
|
|
;
|
|
|
|
|
|
+parameter_pack_identifier:
|
|
|
+ ELLIPSIS
|
|
|
+{
|
|
|
+ $$ = new CPPInstanceIdentifier((CPPIdentifier *)NULL);
|
|
|
+ $$->_packed = true;
|
|
|
+}
|
|
|
+ | ELLIPSIS name
|
|
|
+{
|
|
|
+ $$ = new CPPInstanceIdentifier($2);
|
|
|
+ $$->_packed = true;
|
|
|
+}
|
|
|
+ | KW_CONST parameter_pack_identifier %prec UNARY
|
|
|
+{
|
|
|
+ $$ = $2;
|
|
|
+ $$->add_modifier(IIT_const);
|
|
|
+}
|
|
|
+ | KW_VOLATILE parameter_pack_identifier %prec UNARY
|
|
|
+{
|
|
|
+ $$ = $2;
|
|
|
+ $$->add_modifier(IIT_volatile);
|
|
|
+}
|
|
|
+ | '*' parameter_pack_identifier %prec UNARY
|
|
|
+{
|
|
|
+ $$ = $2;
|
|
|
+ $$->add_modifier(IIT_pointer);
|
|
|
+}
|
|
|
+ | '&' parameter_pack_identifier %prec UNARY
|
|
|
+{
|
|
|
+ $$ = $2;
|
|
|
+ $$->add_modifier(IIT_reference);
|
|
|
+}
|
|
|
+ | ANDAND parameter_pack_identifier %prec UNARY
|
|
|
+{
|
|
|
+ $$ = $2;
|
|
|
+ $$->add_modifier(IIT_rvalue_reference);
|
|
|
+}
|
|
|
+ | SCOPING '*' parameter_pack_identifier %prec UNARY
|
|
|
+{
|
|
|
+ $$ = $3;
|
|
|
+ $$->add_scoped_pointer_modifier($1);
|
|
|
+}
|
|
|
+ | parameter_pack_identifier '[' optional_const_expr ']'
|
|
|
+{
|
|
|
+ $$ = $1;
|
|
|
+ $$->add_array_modifier($3);
|
|
|
+}
|
|
|
+ | '(' parameter_pack_identifier ')' '(' function_parameter_list ')' function_post
|
|
|
+{
|
|
|
+ $$ = $2;
|
|
|
+ $$->add_modifier(IIT_paren);
|
|
|
+ $$->add_func_modifier($5, $7);
|
|
|
+}
|
|
|
+ | '(' parameter_pack_identifier ')'
|
|
|
+{
|
|
|
+ $$ = $2;
|
|
|
+ $$->add_modifier(IIT_paren);
|
|
|
+}
|
|
|
+ ;
|
|
|
+
|
|
|
not_paren_empty_instance_identifier:
|
|
|
empty
|
|
|
{
|
|
|
$$ = new CPPInstanceIdentifier((CPPIdentifier *)NULL);
|
|
|
+}
|
|
|
+ | ELLIPSIS
|
|
|
+{
|
|
|
+ $$ = new CPPInstanceIdentifier((CPPIdentifier *)NULL);
|
|
|
+ $$->_packed = true;
|
|
|
+}
|
|
|
+ | ELLIPSIS name
|
|
|
+{
|
|
|
+ $$ = new CPPInstanceIdentifier($2);
|
|
|
+ $$->_packed = true;
|
|
|
}
|
|
|
| KW_CONST not_paren_empty_instance_identifier %prec UNARY
|
|
|
{
|
|
|
@@ -2016,6 +2124,16 @@ empty_instance_identifier:
|
|
|
empty
|
|
|
{
|
|
|
$$ = new CPPInstanceIdentifier((CPPIdentifier *)NULL);
|
|
|
+}
|
|
|
+ | ELLIPSIS
|
|
|
+{
|
|
|
+ $$ = new CPPInstanceIdentifier((CPPIdentifier *)NULL);
|
|
|
+ $$->_packed = true;
|
|
|
+}
|
|
|
+ | ELLIPSIS name
|
|
|
+{
|
|
|
+ $$ = new CPPInstanceIdentifier($2);
|
|
|
+ $$->_packed = true;
|
|
|
}
|
|
|
| KW_CONST empty_instance_identifier %prec UNARY
|
|
|
{
|
|
|
@@ -2150,6 +2268,16 @@ type:
|
|
|
str << *$3;
|
|
|
yyerror("could not determine type of " + str.str(), @3);
|
|
|
}
|
|
|
+}
|
|
|
+ | KW_UNDERLYING_TYPE '(' full_type ')'
|
|
|
+{
|
|
|
+ CPPEnumType *enum_type = $3->as_enum_type();
|
|
|
+ if (enum_type == NULL) {
|
|
|
+ yyerror("an enumeration type is required", @3);
|
|
|
+ $$ = $3;
|
|
|
+ } else {
|
|
|
+ $$ = enum_type->get_underlying_type();
|
|
|
+ }
|
|
|
}
|
|
|
| KW_AUTO
|
|
|
{
|
|
|
@@ -2157,6 +2285,17 @@ type:
|
|
|
}
|
|
|
;
|
|
|
|
|
|
+type_pack:
|
|
|
+ TYPEPACK_IDENTIFIER
|
|
|
+{
|
|
|
+ $$ = $1->find_type(current_scope, global_scope, false, current_lexer);
|
|
|
+ if ($$ == NULL) {
|
|
|
+ yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
|
|
|
+ }
|
|
|
+ assert($$ != NULL);
|
|
|
+}
|
|
|
+ ;
|
|
|
+
|
|
|
type_decl:
|
|
|
simple_type
|
|
|
{
|
|
|
@@ -2244,6 +2383,16 @@ type_decl:
|
|
|
str << *$3;
|
|
|
yyerror("could not determine type of " + str.str(), @3);
|
|
|
}
|
|
|
+}
|
|
|
+ | KW_UNDERLYING_TYPE '(' full_type ')'
|
|
|
+{
|
|
|
+ CPPEnumType *enum_type = $3->as_enum_type();
|
|
|
+ if (enum_type == NULL) {
|
|
|
+ yyerror("an enumeration type is required", @3);
|
|
|
+ $$ = $3;
|
|
|
+ } else {
|
|
|
+ $$ = enum_type->get_underlying_type();
|
|
|
+ }
|
|
|
}
|
|
|
| KW_AUTO
|
|
|
{
|
|
|
@@ -2308,6 +2457,16 @@ predefined_type:
|
|
|
str << *$3;
|
|
|
yyerror("could not determine type of " + str.str(), @3);
|
|
|
}
|
|
|
+}
|
|
|
+ | KW_UNDERLYING_TYPE '(' full_type ')'
|
|
|
+{
|
|
|
+ CPPEnumType *enum_type = $3->as_enum_type();
|
|
|
+ if (enum_type == NULL) {
|
|
|
+ yyerror("an enumeration type is required", @3);
|
|
|
+ $$ = $3;
|
|
|
+ } else {
|
|
|
+ $$ = enum_type->get_underlying_type();
|
|
|
+ }
|
|
|
}
|
|
|
| KW_AUTO
|
|
|
{
|
|
|
@@ -2336,6 +2495,15 @@ full_type:
|
|
|
{
|
|
|
$3->add_modifier(IIT_const);
|
|
|
$$ = $3->unroll_type($2);
|
|
|
+}
|
|
|
+ | type_pack empty_instance_identifier
|
|
|
+{
|
|
|
+ $$ = $2->unroll_type($1);
|
|
|
+}
|
|
|
+ | KW_CONST type_pack empty_instance_identifier
|
|
|
+{
|
|
|
+ $3->add_modifier(IIT_const);
|
|
|
+ $$ = $3->unroll_type($2);
|
|
|
}
|
|
|
;
|
|
|
|
|
|
@@ -2750,6 +2918,7 @@ element:
|
|
|
| CHAR_TOK
|
|
|
| IDENTIFIER
|
|
|
| TYPENAME_IDENTIFIER
|
|
|
+ | TYPEPACK_IDENTIFIER
|
|
|
| SCOPING
|
|
|
| SIMPLE_IDENTIFIER
|
|
|
| ELLIPSIS | OROR | ANDAND
|
|
|
@@ -2768,10 +2937,11 @@ element:
|
|
|
| KW_OPERATOR | KW_OVERRIDE | KW_PRIVATE | KW_PROTECTED
|
|
|
| KW_PUBLIC | KW_PUBLISHED | KW_REGISTER | KW_REINTERPRET_CAST
|
|
|
| KW_RETURN | KW_SHORT | KW_SIGNED | KW_SIZEOF | KW_STATIC
|
|
|
- | KW_STATIC_ASSERT | KW_STATIC_CAST | KW_STRUCT
|
|
|
+ | KW_STATIC_ASSERT | KW_STATIC_CAST | KW_STRUCT | KW_TEMPLATE
|
|
|
| KW_THREAD_LOCAL | KW_THROW | KW_TRUE | KW_TRY | KW_TYPEDEF
|
|
|
- | KW_TYPEID | KW_TYPENAME | KW_UNION | KW_UNSIGNED | KW_USING
|
|
|
- | KW_VIRTUAL | KW_VOID | KW_VOLATILE | KW_WCHAR_T | KW_WHILE
|
|
|
+ | KW_TYPEID | KW_TYPENAME | KW_UNDERLYING_TYPE | KW_UNION
|
|
|
+ | KW_UNSIGNED | KW_USING | KW_VIRTUAL | KW_VOID | KW_VOLATILE
|
|
|
+ | KW_WCHAR_T | KW_WHILE
|
|
|
{
|
|
|
}
|
|
|
| '+' | '-' | '*' | '/' | '&' | '|' | '^' | '!' | '~' | '=' | '%'
|
|
|
@@ -2840,6 +3010,10 @@ no_angle_bracket_const_expr:
|
|
|
| KW_SIZEOF '(' full_type ')' %prec UNARY
|
|
|
{
|
|
|
$$ = new CPPExpression(CPPExpression::sizeof_func($3));
|
|
|
+}
|
|
|
+ | KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::sizeof_ellipsis_func($4));
|
|
|
}
|
|
|
| KW_ALIGNOF '(' full_type ')' %prec UNARY
|
|
|
{
|
|
|
@@ -3078,6 +3252,10 @@ const_expr:
|
|
|
| KW_SIZEOF '(' full_type ')' %prec UNARY
|
|
|
{
|
|
|
$$ = new CPPExpression(CPPExpression::sizeof_func($3));
|
|
|
+}
|
|
|
+ | KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::sizeof_ellipsis_func($4));
|
|
|
}
|
|
|
| KW_ALIGNOF '(' full_type ')' %prec UNARY
|
|
|
{
|
|
|
@@ -3295,6 +3473,74 @@ const_operand:
|
|
|
| '[' capture_list ']' '(' function_parameter_list ')' function_post maybe_trailing_return_type '{' code '}'
|
|
|
{
|
|
|
$$ = NULL;
|
|
|
+}
|
|
|
+ | KW_HAS_VIRTUAL_DESTRUCTOR '(' full_type ')'
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::type_trait(KW_HAS_VIRTUAL_DESTRUCTOR, $3));
|
|
|
+}
|
|
|
+ | KW_IS_ABSTRACT '(' full_type ')'
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_ABSTRACT, $3));
|
|
|
+}
|
|
|
+ | KW_IS_BASE_OF '(' full_type ',' full_type ')'
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_CLASS, $3, $5));
|
|
|
+}
|
|
|
+ | KW_IS_CLASS '(' full_type ')'
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_CLASS, $3));
|
|
|
+}
|
|
|
+ | KW_IS_CONSTRUCTIBLE '(' full_type ')'
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_CONSTRUCTIBLE, $3));
|
|
|
+}
|
|
|
+ | KW_IS_CONSTRUCTIBLE '(' full_type ',' full_type ')'
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_CONSTRUCTIBLE, $3, $5));
|
|
|
+}
|
|
|
+ | KW_IS_CONVERTIBLE_TO '(' full_type ',' full_type ')'
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_CONVERTIBLE_TO, $3, $5));
|
|
|
+}
|
|
|
+ | KW_IS_DESTRUCTIBLE '(' full_type ')'
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_DESTRUCTIBLE, $3));
|
|
|
+}
|
|
|
+ | KW_IS_EMPTY '(' full_type ')'
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_EMPTY, $3));
|
|
|
+}
|
|
|
+ | KW_IS_ENUM '(' full_type ')'
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_ENUM, $3));
|
|
|
+}
|
|
|
+ | KW_IS_FINAL '(' full_type ')'
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_FINAL, $3));
|
|
|
+}
|
|
|
+ | KW_IS_FUNDAMENTAL '(' full_type ')'
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_FUNDAMENTAL, $3));
|
|
|
+}
|
|
|
+ | KW_IS_POD '(' full_type ')'
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_POD, $3));
|
|
|
+}
|
|
|
+ | KW_IS_POLYMORPHIC '(' full_type ')'
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_POLYMORPHIC, $3));
|
|
|
+}
|
|
|
+ | KW_IS_STANDARD_LAYOUT '(' full_type ')'
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_STANDARD_LAYOUT, $3));
|
|
|
+}
|
|
|
+ | KW_IS_TRIVIAL '(' full_type ')'
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_TRIVIAL, $3));
|
|
|
+}
|
|
|
+ | KW_IS_UNION '(' full_type ')'
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_UNION, $3));
|
|
|
}
|
|
|
;
|
|
|
|
|
|
@@ -3333,6 +3579,10 @@ formal_const_expr:
|
|
|
| KW_SIZEOF '(' full_type ')' %prec UNARY
|
|
|
{
|
|
|
$$ = new CPPExpression(CPPExpression::sizeof_func($3));
|
|
|
+}
|
|
|
+ | KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
|
|
|
+{
|
|
|
+ $$ = new CPPExpression(CPPExpression::sizeof_ellipsis_func($4));
|
|
|
}
|
|
|
| KW_ALIGNOF '(' full_type ')' %prec UNARY
|
|
|
{
|
|
|
@@ -3575,6 +3825,12 @@ class_derivation_name:
|
|
|
| KW_TYPENAME name
|
|
|
{
|
|
|
$$ = CPPType::new_type(new CPPTBDType($2));
|
|
|
+}
|
|
|
+ | name ELLIPSIS
|
|
|
+{
|
|
|
+ CPPClassTemplateParameter *ctp = new CPPClassTemplateParameter($1);
|
|
|
+ ctp->_packed = true;
|
|
|
+ $$ = CPPType::new_type(ctp);
|
|
|
}
|
|
|
;
|
|
|
|
|
|
@@ -3607,6 +3863,10 @@ name:
|
|
|
| TYPENAME_IDENTIFIER
|
|
|
{
|
|
|
$$ = $1;
|
|
|
+}
|
|
|
+ | TYPEPACK_IDENTIFIER
|
|
|
+{
|
|
|
+ $$ = $1;
|
|
|
}
|
|
|
| KW_FINAL
|
|
|
{
|
|
|
@@ -3652,6 +3912,10 @@ name_no_final:
|
|
|
| TYPENAME_IDENTIFIER
|
|
|
{
|
|
|
$$ = $1;
|
|
|
+}
|
|
|
+ | TYPEPACK_IDENTIFIER
|
|
|
+{
|
|
|
+ $$ = $1;
|
|
|
}
|
|
|
| KW_OVERRIDE
|
|
|
{
|