cppparser: support sizeof operator with constexpr

This commit is contained in:
rdb 2020-06-14 12:12:27 +02:00
parent 43961718fa
commit 16f2958adb
3 changed files with 62 additions and 46 deletions

View File

@ -3278,17 +3278,9 @@ no_angle_bracket_const_expr:
{
$$ = new CPPExpression(CPPExpression::sizeof_func($3));
}
| KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
| KW_SIZEOF no_angle_bracket_const_expr %prec UNARY
{
CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
if (arg == nullptr) {
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()));
}
$$ = new CPPExpression(CPPExpression::sizeof_func($2));
}
| KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
{
@ -3402,9 +3394,9 @@ no_angle_bracket_const_expr:
{
$$ = new CPPExpression('f', $1);
}
| no_angle_bracket_const_expr '.' no_angle_bracket_const_expr
| no_angle_bracket_const_expr '.' name
{
$$ = new CPPExpression('.', $1, $3);
$$ = new CPPExpression('.', $1, new CPPExpression($3, current_scope, global_scope, current_lexer));
}
| no_angle_bracket_const_expr POINTSAT no_angle_bracket_const_expr
{
@ -3542,17 +3534,9 @@ const_expr:
{
$$ = new CPPExpression(CPPExpression::sizeof_func($3));
}
| KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
| KW_SIZEOF const_expr %prec UNARY
{
CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
if (arg == nullptr) {
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()));
}
$$ = new CPPExpression(CPPExpression::sizeof_func($2));
}
| KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
{
@ -3704,9 +3688,9 @@ const_expr:
{
$$ = new CPPExpression('f', $1);
}
| const_expr '.' const_expr
| const_expr '.' name
{
$$ = new CPPExpression('.', $1, $3);
$$ = new CPPExpression('.', $1, new CPPExpression($3, current_scope, global_scope, current_lexer));
}
| const_expr POINTSAT const_expr
{
@ -3886,17 +3870,9 @@ formal_const_expr:
{
$$ = new CPPExpression(CPPExpression::sizeof_func($3));
}
| KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
| KW_SIZEOF formal_const_expr %prec UNARY
{
CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
if (arg == nullptr) {
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()));
}
$$ = new CPPExpression(CPPExpression::sizeof_func($2));
}
| KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
{
@ -4044,9 +4020,9 @@ formal_const_expr:
{
$$ = new CPPExpression('f', $1);
}
| formal_const_expr '.' const_expr
| formal_const_expr '.' name
{
$$ = new CPPExpression('.', $1, $3);
$$ = new CPPExpression('.', $1, new CPPExpression($3, current_scope, global_scope, current_lexer));
}
| formal_const_expr POINTSAT const_expr
{

View File

@ -429,12 +429,24 @@ type_trait(int trait, CPPType *type, CPPType *arg) {
CPPExpression CPPExpression::
sizeof_func(CPPType *type) {
CPPExpression expr(0);
expr._type = T_sizeof;
expr._type = T_sizeof_type;
expr._u._typecast._to = type;
expr._u._typecast._op1 = nullptr;
return expr;
}
/**
*
*/
CPPExpression CPPExpression::
sizeof_func(CPPExpression *op1) {
CPPExpression expr(0);
expr._type = T_sizeof_expr;
expr._u._typecast._to = nullptr;
expr._u._typecast._op1 = op1;
return expr;
}
/**
*
*/
@ -629,7 +641,8 @@ evaluate() const {
case T_empty_aggregate_init:
case T_new:
case T_default_new:
case T_sizeof:
case T_sizeof_type:
case T_sizeof_expr:
case T_sizeof_ellipsis:
return Result();
@ -1058,7 +1071,8 @@ determine_type() const {
case T_default_new:
return CPPType::new_type(new CPPPointerType(_u._typecast._to));
case T_sizeof:
case T_sizeof_type:
case T_sizeof_expr:
case T_sizeof_ellipsis:
case T_alignof:
// Note: this should actually be size_t, but that is defined as a typedef
@ -1334,10 +1348,13 @@ is_fully_specified() const {
case T_default_construct:
case T_empty_aggregate_init:
case T_default_new:
case T_sizeof:
case T_sizeof_type:
case T_alignof:
return _u._typecast._to->is_fully_specified();
case T_sizeof_expr:
return _u._typecast._op1->is_fully_specified();
case T_sizeof_ellipsis:
return _u._ident->is_fully_specified();
@ -1469,7 +1486,7 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
case T_default_construct:
case T_empty_aggregate_init:
case T_default_new:
case T_sizeof:
case T_sizeof_type:
case T_alignof:
rep->_u._typecast._to =
_u._typecast._to->substitute_decl(subst, current_scope, global_scope)
@ -1477,6 +1494,13 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
any_changed = any_changed || (rep->_u._typecast._to != _u._typecast._to);
break;
case T_sizeof_expr:
rep->_u._typecast._op1 =
_u._typecast._op1->substitute_decl(subst, current_scope, global_scope)
->as_expression();
any_changed = any_changed || (rep->_u._typecast._op1 != _u._typecast._op1);
break;
case T_trinary_operation:
rep->_u._op._op3 =
_u._op._op3->substitute_decl(subst, current_scope, global_scope)
@ -1567,10 +1591,13 @@ is_tbd() const {
case T_new:
case T_default_construct:
case T_default_new:
case T_sizeof:
case T_sizeof_type:
case T_alignof:
return _u._typecast._to->is_tbd();
case T_sizeof_expr:
return _u._typecast._op1->is_tbd();
case T_trinary_operation:
if (_u._op._op3->is_tbd()) {
return true;
@ -1807,12 +1834,17 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool) const {
out << "())";
break;
case T_sizeof:
case T_sizeof_type:
out << "sizeof(";
_u._typecast._to->output(out, indent_level, scope, false);
out << ")";
break;
case T_sizeof_expr:
out << "sizeof ";
_u._typecast._op1->output(out, indent_level, scope, false);
break;
case T_sizeof_ellipsis:
out << "sizeof...(";
_u._ident->output(out, scope);
@ -2222,10 +2254,13 @@ is_equal(const CPPDeclaration *other) const {
case T_default_construct:
case T_empty_aggregate_init:
case T_default_new:
case T_sizeof:
case T_sizeof_type:
case T_alignof:
return _u._typecast._to == ot->_u._typecast._to;
case T_sizeof_expr:
return _u._typecast._op1 == ot->_u._typecast._op1;
case T_unary_operation:
return *_u._op._op1 == *ot->_u._op._op1;
@ -2324,10 +2359,13 @@ is_less(const CPPDeclaration *other) const {
case T_default_construct:
case T_empty_aggregate_init:
case T_default_new:
case T_sizeof:
case T_sizeof_type:
case T_alignof:
return _u._typecast._to < ot->_u._typecast._to;
case T_sizeof_expr:
return _u._typecast._op1 < ot->_u._typecast._op1;
case T_trinary_operation:
if (*_u._op._op3 != *ot->_u._op._op3) {
return *_u._op._op3 < *ot->_u._op._op3;

View File

@ -52,7 +52,8 @@ public:
T_empty_aggregate_init,
T_new,
T_default_new,
T_sizeof,
T_sizeof_type,
T_sizeof_expr,
T_sizeof_ellipsis,
T_alignof,
T_unary_operation,
@ -89,6 +90,7 @@ public:
static CPPExpression typeid_op(CPPExpression *op1, CPPType *std_type_info);
static CPPExpression type_trait(int trait, CPPType *type, CPPType *arg = nullptr);
static CPPExpression sizeof_func(CPPType *type);
static CPPExpression sizeof_func(CPPExpression *op1);
static CPPExpression sizeof_ellipsis_func(CPPIdentifier *ident);
static CPPExpression alignof_func(CPPType *type);
static CPPExpression lambda(CPPClosureType *type);