|
|
@@ -249,6 +249,8 @@ pop_struct() {
|
|
|
%token XOREQUAL
|
|
|
%token LSHIFTEQUAL
|
|
|
%token RSHIFTEQUAL
|
|
|
+%token ATTR_LEFT
|
|
|
+%token ATTR_RIGHT
|
|
|
|
|
|
%token KW_ALIGNAS
|
|
|
%token KW_ALIGNOF
|
|
|
@@ -874,10 +876,18 @@ storage_class:
|
|
|
{
|
|
|
$$ = $2 | (int)CPPInstance::SC_thread_local;
|
|
|
}
|
|
|
- | '[' '[' attribute_specifiers ']' ']' storage_class
|
|
|
+ | ATTR_LEFT attribute_specifiers ATTR_RIGHT storage_class
|
|
|
{
|
|
|
// Ignore attribute specifiers for now.
|
|
|
- $$ = $6;
|
|
|
+ $$ = $4;
|
|
|
+}
|
|
|
+ | KW_ALIGNAS '(' const_expr ')' storage_class
|
|
|
+{
|
|
|
+ $$ = $5;
|
|
|
+}
|
|
|
+ | KW_ALIGNAS '(' type_decl ')' storage_class
|
|
|
+{
|
|
|
+ $$ = $5;
|
|
|
}
|
|
|
;
|
|
|
|
|
|
@@ -889,6 +899,7 @@ attribute_specifiers:
|
|
|
attribute_specifier:
|
|
|
name
|
|
|
| name '(' formal_parameter_list ')'
|
|
|
+ | KW_USING name ':' attribute_specifier
|
|
|
;
|
|
|
|
|
|
type_like_declaration:
|
|
|
@@ -1272,10 +1283,10 @@ function_post:
|
|
|
{
|
|
|
$$ = $1;
|
|
|
}
|
|
|
-/* | function_post '[' '[' attribute_specifiers ']' ']'
|
|
|
+ | function_post ATTR_LEFT attribute_specifiers ATTR_RIGHT
|
|
|
{
|
|
|
$$ = $1;
|
|
|
-}*/
|
|
|
+}
|
|
|
;
|
|
|
|
|
|
function_operator:
|
|
|
@@ -1443,7 +1454,8 @@ more_template_declaration:
|
|
|
;
|
|
|
|
|
|
template_declaration:
|
|
|
- KW_TEMPLATE
|
|
|
+ KW_EXTERN template_declaration
|
|
|
+ | KW_TEMPLATE
|
|
|
{
|
|
|
push_scope(new CPPTemplateScope(current_scope));
|
|
|
}
|
|
|
@@ -1451,7 +1463,7 @@ template_declaration:
|
|
|
{
|
|
|
pop_scope();
|
|
|
}
|
|
|
- | KW_TEMPLATE type_like_declaration
|
|
|
+ | KW_TEMPLATE type_like_declaration
|
|
|
;
|
|
|
|
|
|
template_formal_parameters:
|
|
|
@@ -1903,6 +1915,10 @@ function_parameter:
|
|
|
| KW_REGISTER function_parameter
|
|
|
{
|
|
|
$$ = $2;
|
|
|
+}
|
|
|
+ | ATTR_LEFT attribute_specifiers ATTR_RIGHT function_parameter
|
|
|
+{
|
|
|
+ $$ = $4;
|
|
|
}
|
|
|
;
|
|
|
|
|
|
@@ -2246,16 +2262,16 @@ type:
|
|
|
{
|
|
|
$$ = CPPType::new_type($1);
|
|
|
}
|
|
|
- | struct_keyword name
|
|
|
+ | struct_keyword struct_attributes name
|
|
|
{
|
|
|
- CPPType *type = $2->find_type(current_scope, global_scope, false, current_lexer);
|
|
|
+ CPPType *type = $3->find_type(current_scope, global_scope, false, current_lexer);
|
|
|
if (type != NULL) {
|
|
|
$$ = type;
|
|
|
} else {
|
|
|
CPPExtensionType *et =
|
|
|
- CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
|
|
|
+ CPPType::new_type(new CPPExtensionType($1, $3, current_scope, @1.file))
|
|
|
->as_extension_type();
|
|
|
- CPPScope *scope = $2->get_scope(current_scope, global_scope);
|
|
|
+ CPPScope *scope = $3->get_scope(current_scope, global_scope);
|
|
|
if (scope != NULL) {
|
|
|
scope->define_extension_type(et);
|
|
|
}
|
|
|
@@ -2286,6 +2302,10 @@ type:
|
|
|
str << *$3;
|
|
|
yyerror("could not determine type of " + str.str(), @3);
|
|
|
}
|
|
|
+}
|
|
|
+ | KW_DECLTYPE '(' KW_AUTO ')'
|
|
|
+{
|
|
|
+ $$ = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto));
|
|
|
}
|
|
|
| KW_UNDERLYING_TYPE '(' full_type ')'
|
|
|
{
|
|
|
@@ -2343,16 +2363,16 @@ type_decl:
|
|
|
{
|
|
|
$$ = new CPPTypeDeclaration(CPPType::new_type($1));
|
|
|
}
|
|
|
- | struct_keyword name
|
|
|
+ | struct_keyword struct_attributes name
|
|
|
{
|
|
|
- CPPType *type = $2->find_type(current_scope, global_scope, false, current_lexer);
|
|
|
+ CPPType *type = $3->find_type(current_scope, global_scope, false, current_lexer);
|
|
|
if (type != NULL) {
|
|
|
$$ = type;
|
|
|
} else {
|
|
|
CPPExtensionType *et =
|
|
|
- CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
|
|
|
+ CPPType::new_type(new CPPExtensionType($1, $3, current_scope, @1.file))
|
|
|
->as_extension_type();
|
|
|
- CPPScope *scope = $2->get_scope(current_scope, global_scope);
|
|
|
+ CPPScope *scope = $3->get_scope(current_scope, global_scope);
|
|
|
if (scope != NULL) {
|
|
|
scope->define_extension_type(et);
|
|
|
}
|
|
|
@@ -2401,6 +2421,10 @@ type_decl:
|
|
|
str << *$3;
|
|
|
yyerror("could not determine type of " + str.str(), @3);
|
|
|
}
|
|
|
+}
|
|
|
+ | KW_DECLTYPE '(' KW_AUTO ')'
|
|
|
+{
|
|
|
+ $$ = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto));
|
|
|
}
|
|
|
| KW_UNDERLYING_TYPE '(' full_type ')'
|
|
|
{
|
|
|
@@ -2435,16 +2459,16 @@ predefined_type:
|
|
|
{
|
|
|
$$ = CPPType::new_type(new CPPTBDType($2));
|
|
|
}
|
|
|
- | struct_keyword name
|
|
|
+ | struct_keyword struct_attributes name
|
|
|
{
|
|
|
- CPPType *type = $2->find_type(current_scope, global_scope, false, current_lexer);
|
|
|
+ CPPType *type = $3->find_type(current_scope, global_scope, false, current_lexer);
|
|
|
if (type != NULL) {
|
|
|
$$ = type;
|
|
|
} else {
|
|
|
CPPExtensionType *et =
|
|
|
- CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
|
|
|
+ CPPType::new_type(new CPPExtensionType($1, $3, current_scope, @1.file))
|
|
|
->as_extension_type();
|
|
|
- CPPScope *scope = $2->get_scope(current_scope, global_scope);
|
|
|
+ CPPScope *scope = $3->get_scope(current_scope, global_scope);
|
|
|
if (scope != NULL) {
|
|
|
scope->define_extension_type(et);
|
|
|
}
|
|
|
@@ -2525,8 +2549,15 @@ full_type:
|
|
|
}
|
|
|
;
|
|
|
|
|
|
+struct_attributes:
|
|
|
+ empty
|
|
|
+ | struct_attributes ATTR_LEFT attribute_specifiers ATTR_RIGHT
|
|
|
+ | struct_attributes KW_ALIGNAS '(' const_expr ')'
|
|
|
+ | struct_attributes KW_ALIGNAS '(' type_decl ')'
|
|
|
+ ;
|
|
|
+
|
|
|
anonymous_struct:
|
|
|
- struct_keyword '{'
|
|
|
+ struct_keyword struct_attributes '{'
|
|
|
{
|
|
|
CPPVisibility starting_vis =
|
|
|
($1 == CPPExtensionType::T_class) ? V_private : V_public;
|
|
|
@@ -2550,19 +2581,19 @@ anonymous_struct:
|
|
|
;
|
|
|
|
|
|
named_struct:
|
|
|
- struct_keyword name_no_final
|
|
|
+ struct_keyword struct_attributes name_no_final
|
|
|
{
|
|
|
CPPVisibility starting_vis =
|
|
|
($1 == CPPExtensionType::T_class) ? V_private : V_public;
|
|
|
|
|
|
- CPPScope *scope = $2->get_scope(current_scope, global_scope, current_lexer);
|
|
|
+ CPPScope *scope = $3->get_scope(current_scope, global_scope, current_lexer);
|
|
|
if (scope == NULL) {
|
|
|
scope = current_scope;
|
|
|
}
|
|
|
- CPPScope *new_scope = new CPPScope(scope, $2->_names.back(),
|
|
|
+ CPPScope *new_scope = new CPPScope(scope, $3->_names.back(),
|
|
|
starting_vis);
|
|
|
|
|
|
- CPPStructType *st = new CPPStructType($1, $2, current_scope,
|
|
|
+ CPPStructType *st = new CPPStructType($1, $3, current_scope,
|
|
|
new_scope, @1.file);
|
|
|
new_scope->set_struct_type(st);
|
|
|
current_scope->define_extension_type(st);
|
|
|
@@ -2945,6 +2976,7 @@ element:
|
|
|
| SCOPE | PLUSPLUS | MINUSMINUS
|
|
|
| TIMESEQUAL | DIVIDEEQUAL | MODEQUAL | PLUSEQUAL | MINUSEQUAL
|
|
|
| OREQUAL | ANDEQUAL | XOREQUAL | LSHIFTEQUAL | RSHIFTEQUAL
|
|
|
+ | ATTR_LEFT | ATTR_RIGHT
|
|
|
| KW_ALIGNAS | KW_ALIGNOF | KW_AUTO | KW_BOOL | KW_CATCH
|
|
|
| KW_CHAR | KW_CHAR16_T | KW_CHAR32_T | KW_CLASS | KW_CONST
|
|
|
| KW_CONSTEXPR | KW_CONST_CAST | KW_DECLTYPE | KW_DEFAULT
|
|
|
@@ -3028,6 +3060,18 @@ no_angle_bracket_const_expr:
|
|
|
| KW_SIZEOF '(' full_type ')' %prec UNARY
|
|
|
{
|
|
|
$$ = new CPPExpression(CPPExpression::sizeof_func($3));
|
|
|
+}
|
|
|
+ | KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
|
|
|
+{
|
|
|
+ CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
|
|
|
+ if (arg == (CPPDeclaration *)NULL) {
|
|
|
+ yyerror("undefined sizeof argument: " + $3->get_fully_scoped_name(), @3);
|
|
|
+ } else if (arg->get_subtype() == CPPDeclaration::ST_instance) {
|
|
|
+ CPPInstance *inst = arg->as_instance();
|
|
|
+ $$ = new CPPExpression(CPPExpression::sizeof_func(inst->_type));
|
|
|
+ } else {
|
|
|
+ $$ = new CPPExpression(CPPExpression::sizeof_func(arg->as_type()));
|
|
|
+ }
|
|
|
}
|
|
|
| KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
|
|
|
{
|
|
|
@@ -3190,6 +3234,16 @@ const_expr:
|
|
|
}
|
|
|
assert(type != NULL);
|
|
|
$$ = new CPPExpression(CPPExpression::construct_op(type, $3));
|
|
|
+}
|
|
|
+ | TYPENAME_IDENTIFIER '{' optional_const_expr_comma '}'
|
|
|
+{
|
|
|
+ // Aggregate initialization.
|
|
|
+ CPPType *type = $1->find_type(current_scope, global_scope, false, current_lexer);
|
|
|
+ if (type == NULL) {
|
|
|
+ yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
|
|
|
+ }
|
|
|
+ assert(type != NULL);
|
|
|
+ $$ = new CPPExpression(CPPExpression::aggregate_init_op(type, $3));
|
|
|
}
|
|
|
| KW_INT '(' optional_const_expr_comma ')'
|
|
|
{
|
|
|
@@ -3270,6 +3324,18 @@ const_expr:
|
|
|
| KW_SIZEOF '(' full_type ')' %prec UNARY
|
|
|
{
|
|
|
$$ = new CPPExpression(CPPExpression::sizeof_func($3));
|
|
|
+}
|
|
|
+ | KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
|
|
|
+{
|
|
|
+ CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
|
|
|
+ if (arg == (CPPDeclaration *)NULL) {
|
|
|
+ yyerror("undefined sizeof argument: " + $3->get_fully_scoped_name(), @3);
|
|
|
+ } else if (arg->get_subtype() == CPPDeclaration::ST_instance) {
|
|
|
+ CPPInstance *inst = arg->as_instance();
|
|
|
+ $$ = new CPPExpression(CPPExpression::sizeof_func(inst->_type));
|
|
|
+ } else {
|
|
|
+ $$ = new CPPExpression(CPPExpression::sizeof_func(arg->as_type()));
|
|
|
+ }
|
|
|
}
|
|
|
| KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
|
|
|
{
|
|
|
@@ -3602,6 +3668,18 @@ formal_const_expr:
|
|
|
| KW_SIZEOF '(' full_type ')' %prec UNARY
|
|
|
{
|
|
|
$$ = new CPPExpression(CPPExpression::sizeof_func($3));
|
|
|
+}
|
|
|
+ | KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
|
|
|
+{
|
|
|
+ CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
|
|
|
+ if (arg == (CPPDeclaration *)NULL) {
|
|
|
+ yyerror("undefined sizeof argument: " + $3->get_fully_scoped_name(), @3);
|
|
|
+ } else if (arg->get_subtype() == CPPDeclaration::ST_instance) {
|
|
|
+ CPPInstance *inst = arg->as_instance();
|
|
|
+ $$ = new CPPExpression(CPPExpression::sizeof_func(inst->_type));
|
|
|
+ } else {
|
|
|
+ $$ = new CPPExpression(CPPExpression::sizeof_func(arg->as_type()));
|
|
|
+ }
|
|
|
}
|
|
|
| KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
|
|
|
{
|
|
|
@@ -3828,15 +3906,17 @@ capture_list:
|
|
|
{
|
|
|
$$ = new CPPClosureType(CPPClosureType::CT_by_reference);
|
|
|
}
|
|
|
- | capture
|
|
|
+ | capture maybe_initialize
|
|
|
{
|
|
|
$$ = new CPPClosureType();
|
|
|
+ $1->_initializer = $2;
|
|
|
$$->_captures.push_back(*$1);
|
|
|
delete $1;
|
|
|
}
|
|
|
- | capture_list ',' capture
|
|
|
+ | capture_list ',' capture maybe_initialize
|
|
|
{
|
|
|
$$ = $1;
|
|
|
+ $3->_initializer = $4;
|
|
|
$$->_captures.push_back(*$3);
|
|
|
delete $3;
|
|
|
}
|
|
|
@@ -3884,14 +3964,6 @@ class_derivation_name:
|
|
|
type = CPPType::new_type(new CPPTBDType($1));
|
|
|
}
|
|
|
$$ = type;
|
|
|
-}
|
|
|
- | struct_keyword name
|
|
|
-{
|
|
|
- CPPType *type = $2->find_type(current_scope, global_scope, true, current_lexer);
|
|
|
- if (type == NULL) {
|
|
|
- type = CPPType::new_type(new CPPTBDType($2));
|
|
|
- }
|
|
|
- $$ = type;
|
|
|
}
|
|
|
| KW_TYPENAME name
|
|
|
{
|