================ idCompiler::ParseReturnStatement ================ */
| 1697 | ================ |
| 1698 | */ |
| 1699 | void idCompiler::ParseReturnStatement( void ) { |
| 1700 | idVarDef *e; |
| 1701 | etype_t type_a; |
| 1702 | etype_t type_b; |
| 1703 | const opcode_t *op; |
| 1704 | |
| 1705 | if ( CheckToken( ";" ) ) { |
| 1706 | if ( scope->TypeDef()->ReturnType()->Type() != ev_void ) { |
| 1707 | Error( "expecting return value" ); |
| 1708 | } |
| 1709 | |
| 1710 | EmitOpcode( OP_RETURN, 0, 0 ); |
| 1711 | return; |
| 1712 | } |
| 1713 | |
| 1714 | e = GetExpression( TOP_PRIORITY ); |
| 1715 | ExpectToken( ";" ); |
| 1716 | |
| 1717 | type_a = e->Type(); |
| 1718 | type_b = scope->TypeDef()->ReturnType()->Type(); |
| 1719 | |
| 1720 | if ( TypeMatches( type_a, type_b ) ) { |
| 1721 | EmitOpcode( OP_RETURN, e, 0 ); |
| 1722 | return; |
| 1723 | } |
| 1724 | |
| 1725 | for( op = opcodes; op->name; op++ ) { |
| 1726 | if ( !strcmp( op->name, "=" ) ) { |
| 1727 | break; |
| 1728 | } |
| 1729 | } |
| 1730 | |
| 1731 | assert( op->name ); |
| 1732 | |
| 1733 | while( !TypeMatches( type_a, op->type_a->Type() ) || !TypeMatches( type_b, op->type_b->Type() ) ) { |
| 1734 | op++; |
| 1735 | if ( !op->name || strcmp( op->name, "=" ) ) { |
| 1736 | Error( "type mismatch for return value" ); |
| 1737 | } |
| 1738 | } |
| 1739 | |
| 1740 | idTypeDef *returnType = scope->TypeDef()->ReturnType(); |
| 1741 | if ( returnType->Type() == ev_string ) { |
| 1742 | EmitOpcode( op, e, gameLocal.program.returnStringDef ); |
| 1743 | } else { |
| 1744 | gameLocal.program.returnDef->SetTypeDef( returnType ); |
| 1745 | EmitOpcode( op, e, gameLocal.program.returnDef ); |
| 1746 | } |
| 1747 | EmitOpcode( OP_RETURN, 0, 0 ); |
| 1748 | } |
| 1749 | |
| 1750 | /* |
| 1751 | ================ |
nothing calls this directly
no test coverage detected