diff --git a/dtool/src/cppparser/cppBison.yxx b/dtool/src/cppparser/cppBison.yxx index 7a9797148e..f9a2c2ab9b 100644 --- a/dtool/src/cppparser/cppBison.yxx +++ b/dtool/src/cppparser/cppBison.yxx @@ -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 { diff --git a/dtool/src/cppparser/cppExpression.cxx b/dtool/src/cppparser/cppExpression.cxx index 78da68b5a7..2ded01f836 100644 --- a/dtool/src/cppparser/cppExpression.cxx +++ b/dtool/src/cppparser/cppExpression.cxx @@ -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; diff --git a/dtool/src/cppparser/cppExpression.h b/dtool/src/cppparser/cppExpression.h index 3cea871679..cd6030f73d 100644 --- a/dtool/src/cppparser/cppExpression.h +++ b/dtool/src/cppparser/cppExpression.h @@ -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);