PTREE NodeConvertVirtualPtr( // EXECUTE A VIRTUAL BASE CAST PTREE expr, // - expr to cast TYPE final_type, // - final type after cast target_offset_t vb_offset, // - offset of vbptr vindex vb_index ) // - index in vbtable { PTREE offset; TYPE vbptr_type; TYPE adjust_type; PTREE dup; vbptr_type = MakeVBTableFieldType( true ); offset = NodeOffset( vb_offset ); expr = NodeBinary( CO_DOT, expr, offset ); expr->flags |= PTF_LVALUE | PTF_PTR_NONZERO; expr->type = vbptr_type; dup = NodeDupExpr( &expr ); expr->flags |= PTF_LVALUE | PTF_PTR_NONZERO; expr = NodeFetch( expr ); expr->type = vbptr_type; expr->flags &= ~ PTF_LVALUE; expr->flags |= PTF_PTR_NONZERO; adjust_type = TypePointedAtModified( vbptr_type ); offset = NodeOffset( vb_index * CgMemorySize( adjust_type ) ); expr = NodeBinary( CO_DOT, expr, offset ); expr->type = adjust_type; expr->flags |= PTF_LVALUE | PTF_PTR_NONZERO; expr = NodeFetch( expr ); expr->type = adjust_type; expr->flags |= PTF_PTR_NONZERO; expr = NodeBinary( CO_DOT, dup, expr ); expr->type = final_type; expr->flags |= PTF_LVALUE | PTF_PTR_NONZERO; return( expr ); }
static boolean passStructOnStack( // PASS A STRUCT/CLASS ON STACK PTREE arg, // - argument (CO_LIST) unsigned warning ) // - internal-data warning { PTREE right; // - right operand TYPE type; // - class type right = NodeRvalue( arg->u.subtree[1] ); type = right->type; if( right->flags & PTF_CLASS_RVREF ) { if( right->op != PT_ERROR ) { PTREE temp = NodeTemporary( type ); right = ClassDefaultCopyDiag( temp, right, &diagEllConv ); if( right->op != PT_ERROR ) { right = NodeDtorExpr( right, temp->u.symcg.symbol ); if( right->op != PT_ERROR ) { right->type = type; right = NodeFetch( right ); right->flags &= ~PTF_LVALUE; } } } if( right->op == PT_ERROR ) { arg->u.subtree[1] = right; PTreeErrorNode( arg ); return FALSE; } } arg_finish( right, arg ); if( TypeHasSpecialFields( type ) ) { PTreeWarnExpr( arg, warning ); } return TRUE; }