PTREE FoldUnary( PTREE expr ) /***************************/ { PTREE op1; TYPE result_type; bool dont_care; op1 = expr->u.subtree[0]; if( notFoldable( op1 ) ) { switch( expr->cgop ) { case CO_EXCLAMATION: if( nonZeroExpr( op1 ) ) { expr = makeTrueFalse( expr, op1, 0 ); } break; } return( expr ); } result_type = expr->type; if( op1->op == PT_FLOATING_CONSTANT ) { switch( expr->cgop ) { case CO_EXCLAMATION: op1->u.int64_constant.u._32[ I64HI32 ] = 0; op1->u.int64_constant.u._32[ I64LO32 ] = ( BFSign( op1->u.floating_constant ) == 0 ); op1->op = PT_INT_CONSTANT; op1 = NodeSetBooleanType( op1 ); break; case CO_UMINUS: BFNegate( op1->u.floating_constant ); break; case CO_UPLUS: break; default: return( expr ); } op1 = PTreeCopySrcLocation( op1, expr ); PTreeFree( expr ); return( castConstant( op1, result_type, &dont_care ) ); } switch( expr->cgop ) { case CO_TILDE: op1->u.int64_constant.u._32[0] = ~ op1->u.int64_constant.u._32[0]; op1->u.int64_constant.u._32[1] = ~ op1->u.int64_constant.u._32[1]; break; case CO_EXCLAMATION: op1 = makeBooleanConst( op1, ! nonZeroExpr( op1 ) ); break; case CO_UMINUS: U64Neg( &op1->u.int64_constant, &op1->u.int64_constant ); break; case CO_UPLUS: break; default: return( expr ); } op1 = PTreeCopySrcLocation( op1, expr ); PTreeFree( expr ); return( castConstant( op1, result_type, &dont_care ) ); }
PTREE UdcCall // CALL UDC FUNCTION ( PTREE src // - source expression , TYPE udcf_type // - type for udcf , CALL_DIAG* diagnosis ) // - call diagnosis { PTREE node; // - node under construction SEARCH_RESULT* result; // - result for scope diagnosis TYPE class_type; // - class for UDCF class_type = ClassTypeForType( NodeType( src ) ); result = ScopeFindScopedMemberConversion ( class_type->u.c.scope , NULL , udcf_type , TF1_NULL ); node = NodeMakeCallee( result->sym ); node->u.symcg.result = result; node->cgop = CO_NAME_CONVERT; node = NodeDottedFunction( src, node ); node = PTreeCopySrcLocation( node, src ); node = NodeBinary( CO_CALL_NOOVLD, node, NULL ); node = PTreeCopySrcLocation( node, src ); node = AnalyseCall( node, diagnosis ); return node; }
static PTREE insert // INSERT AT NODE ( PTREE node // - node , NAME name ) // - routine name { PTREE left; // - new left operand PTREE comma; // - new comma node left = PTreeId( name ); left = PTreeCopySrcLocation( left, node ); left = PTreeBinary( CO_CALL, left, NULL ); left = PTreeCopySrcLocation( left, node ); comma = PTreeBinary( CO_COMMA, left, node ); comma = PTreeCopySrcLocation( comma, node ); return comma; }
static PTREE castFloatingConstant( PTREE expr, TYPE type, bool *happened ) { target_long value; PTREE new_expr; type_id id; id = TypedefModifierRemove( type )->id; switch( id ) { case TYP_POINTER: case TYP_MEMBER_POINTER: id = TYP_ULONG; // drops thru case TYP_SCHAR: case TYP_SSHORT: case TYP_SINT: case TYP_SLONG: case TYP_UCHAR: case TYP_USHORT: case TYP_UINT: case TYP_ULONG: case TYP_WCHAR: value = BFGetLong( &(expr->u.floating_constant) ); new_expr = PTreeIntConstant( (target_ulong) value, id ); new_expr = CastIntConstant( new_expr, type, happened ); break; case TYP_FLOAT: { float_handle flt_val; flt_val = BFCopy( expr->u.floating_constant ); new_expr = PTreeFloatingConstant( flt_val, id ); } break; case TYP_LONG_DOUBLE: case TYP_DOUBLE: { float_handle flt_val; flt_val = BFCopy( expr->u.floating_constant ); new_expr = PTreeFloatingConstant( flt_val, id ); } break; case TYP_SLONG64: case TYP_ULONG64: { signed_64 val = BFCnvF64( expr->u.floating_constant ); new_expr = PTreeInt64Constant( val, id ); } break; default: return( expr ); } *happened = true; new_expr = PTreeCopySrcLocation( new_expr, expr ); PTreeFree( expr ); return( new_expr ); }
static PTREE pruneExpr( // PRUNE ONE SIDE FROM EXPRESSION PTREE orig, // - original expression PTREE* ref, // - subtree[0] or [1] in orig PTREE undec ) // - undecorated result { if( *ref == undec ) { *ref = NULL; } else { (*ref)->u.subtree[1] = NULL; } undec = PTreeCopySrcLocation( undec, orig ); NodeFreeDupedExpr( orig ); return undec; }
static PTREE makeTrueFalse( PTREE expr, PTREE op, int value ) { PTREE node; if(( op->flags & PTF_SIDE_EFF ) != 0 ) { return( expr ); } if( anachronismFound( op ) ) { return( expr ); } node = NodeOffset( value ); node = NodeSetBooleanType( node ); node = PTreeCopySrcLocation( node, expr ); NodeFreeDupedExpr( expr ); return( node ); }
PTREE CastIntConstant( PTREE expr, TYPE type, bool *happened ) { PTREE new_expr; target_ulong ul_val; float_handle dbl_val; type_id id; bool signed_type; signed_type = SignedIntType( expr->type ); id = TypedefModifierRemove( type )->id; ul_val = expr->u.uint_constant; if( NULL == Integral64Type( expr->type ) ) { switch( id ) { case TYP_SCHAR: ul_val = (target_schar) ul_val; /* fall through */ case TYP_SSHORT: ul_val = (target_short) ul_val; /* fall through */ case TYP_SINT: ul_val = (target_int) ul_val; /* fall through */ case TYP_SLONG: ul_val = (target_long) ul_val; new_expr = PTreeIntConstant( ul_val, id ); break; case TYP_UCHAR: ul_val = (target_uchar) ul_val; /* fall through */ case TYP_USHORT: ul_val = (target_ushort) ul_val; /* fall through */ case TYP_UINT: ul_val = (target_uint) ul_val; /* fall through */ case TYP_ULONG: ul_val = (target_ulong) ul_val; new_expr = PTreeIntConstant( ul_val, id ); break; case TYP_ULONG64: case TYP_SLONG64: if( PT_FLOATING_CONSTANT == expr->op ) { new_expr = PTreeInt64Constant ( BFCnvF64( expr->u.floating_constant ) , id ); } else { new_expr = PTreeInt64Constant( expr->u.int64_constant, id ); } break; case TYP_POINTER: case TYP_MEMBER_POINTER: ul_val = (target_ulong) ul_val; new_expr = PTreeIntConstant( ul_val, TYP_ULONG ); new_expr->type = type; break; case TYP_FLOAT: #if 0 // these are now identical, with canonical floating point if( signed_type ) { flt_val = BFCnvIF( expr->u.int_constant ); } else { flt_val = BFCnvUF( expr->u.uint_constant ); } new_expr = PTreeFloatingConstant( flt_val, id ); break; #endif case TYP_LONG_DOUBLE: case TYP_DOUBLE: if( signed_type ) { dbl_val = BFCnvIF( expr->u.int_constant ); } else { dbl_val = BFCnvUF( expr->u.uint_constant ); } new_expr = PTreeFloatingConstant( dbl_val, id ); break; case TYP_WCHAR: ul_val = (target_wchar) ul_val; new_expr = PTreeIntConstant( ul_val, id ); break; default: return( expr ); } } else { ul_val = expr->u.int_constant; switch( id ) { case TYP_SCHAR: ul_val = (target_schar) ul_val; /* fall through */ case TYP_SSHORT: ul_val = (target_short) ul_val; /* fall through */ case TYP_SINT: ul_val = (target_int) ul_val; /* fall through */ case TYP_SLONG: ul_val = (target_long) ul_val; new_expr = PTreeIntConstant( ul_val, id ); break; case TYP_SLONG64: case TYP_ULONG64: new_expr = PTreeInt64Constant( expr->u.int64_constant, id ); break; case TYP_UCHAR: ul_val = (target_uchar) ul_val; /* fall through */ case TYP_USHORT: ul_val = (target_ushort) ul_val; /* fall through */ case TYP_UINT: ul_val = (target_uint) ul_val; /* fall through */ case TYP_ULONG: ul_val = (target_ulong) ul_val; new_expr = PTreeIntConstant( ul_val, id ); break; case TYP_POINTER: case TYP_MEMBER_POINTER: ul_val = (target_ulong) ul_val; new_expr = PTreeIntConstant( ul_val, TYP_ULONG ); new_expr->type = type; break; case TYP_FLOAT: #if 0 // these are now identical, with canonical floating point if( signed_type ) { flt_val = BFCnvI64F( expr->u.int64_constant ); } else { flt_val = BFCnvU64F( expr->u.uint64_constant ); } new_expr = PTreeFloatingConstant( flt_val, id ); break; #endif case TYP_LONG_DOUBLE: case TYP_DOUBLE: if( signed_type ) { dbl_val = BFCnvI64F( expr->u.int64_constant ); } else { dbl_val = BFCnvU64F( expr->u.int64_constant ); } new_expr = PTreeFloatingConstant( dbl_val, id ); break; case TYP_WCHAR: ul_val = (target_wchar) ul_val; new_expr = PTreeIntConstant( ul_val, id ); break; default: return( expr ); } } *happened = true; new_expr->flags = expr->flags; new_expr = PTreeCopySrcLocation( new_expr, expr ); PTreeFree( expr ); return( new_expr ); }
PTREE FoldBinary( PTREE expr ) /****************************/ { PTREE orig1; PTREE orig2; PTREE op1; PTREE op2; PTREE op_t; PTREE op_f; PTREE op_test; TYPE type; unsigned typ1; unsigned typ2; bool cast_happened; bool has_decoration_left; bool has_decoration_right; bool has_decoration; type = expr->type; orig1 = expr->u.subtree[0]; orig2 = expr->u.subtree[1]; type = expr->type; op1 = overCondDecor( orig1 ); has_decoration_left = op1 != orig1; op2 = overCondDecor( orig2 ); has_decoration_right = op2 != orig2; has_decoration = has_decoration_left | has_decoration_left; if( notFoldable( op1 ) ) { if( notFoldable( op2 ) ) { return( expr ); } switch( expr->cgop ) { case CO_EQ: DbgVerify( ! has_decoration, "FoldBinary -- bad ==" ); if( zeroConstant( op2 ) ) { if( zeroConstant( op1 ) ) { expr = makeTrueFalse( expr, op1, 1 ); } else if( nonZeroExpr( op1 ) ) { expr = makeTrueFalse( expr, op1, 0 ); } } break; case CO_NE: DbgVerify( ! has_decoration, "FoldBinary -- bad !=" ); if( zeroConstant( op2 ) ) { if( zeroConstant( op1 ) ) { expr = makeTrueFalse( expr, op1, 0 ); } else if( nonZeroExpr( op1 ) ) { expr = makeTrueFalse( expr, op1, 1 ); } } break; case CO_PLUS_EQUAL : case CO_MINUS_EQUAL : case CO_AND_EQUAL : case CO_OR_EQUAL : case CO_XOR_EQUAL : case CO_EQUAL: /* have to be careful with pointer scaling of numbers */ DbgVerify( ! has_decoration, "FoldBinary -- bad equals" ); if( ArithType( type ) != NULL ) { expr->u.subtree[1] = castConstant( op2, type, &cast_happened ); } break; case CO_CONVERT: DbgVerify( ! has_decoration, "FoldBinary -- bad convert" ); op_test = castConstant( op2, type, &cast_happened ); if( cast_happened ) { /* op2 was freed */ op_test = PTreeCopySrcLocation( op_test, expr ); NodeFreeDupedExpr( op1 ); PTreeFree( expr ); return( op_test ); } break; case CO_COMMA : // // X, c -- can be optimized when X is PT_IC( IC_COND_TRUE ) // and comma node has PTF_COND_END set // if( (expr->flags & PTF_COND_END) && op1->op == PT_IC && op1->u.ic.opcode == IC_COND_TRUE ) { expr = pruneExpr( expr, &expr->u.subtree[1], op2 ); } break; } return( expr ); } if( notFoldable( op2 ) ) { switch( expr->cgop ) { case CO_EQ: DbgVerify( ! has_decoration, "FoldBinary -- bad ==" ); if( zeroConstant( op1 ) ) { if( zeroConstant( op2 ) ) { expr = makeTrueFalse( expr, op2, 1 ); } else if( nonZeroExpr( op2 ) ) { expr = makeTrueFalse( expr, op2, 0 ); } } break; case CO_NE: DbgVerify( ! has_decoration, "FoldBinary -- bad !=" ); if( zeroConstant( op1 ) ) { if( zeroConstant( op2 ) ) { expr = makeTrueFalse( expr, op2, 0 ); } else if( nonZeroExpr( op2 ) ) { expr = makeTrueFalse( expr, op2, 1 ); } } break; case CO_AND_AND: // DbgVerify( has_decoration, "FoldBinary -- bad &&" ); if( ! zeroConstant( op1 ) ) { /* 1 && X => X (X is already boolean) */ expr = pruneExpr( expr, &expr->u.subtree[1], op2 ); } else { /* 0 && X => 0 */ return pruneExpr( expr, &expr->u.subtree[0], op1 ); } break; case CO_OR_OR: // DbgVerify( has_decoration, "FoldBinary -- bad ||" ); if( zeroConstant( op1 ) ) { /* 0 || X => X (X is already boolean) */ return pruneExpr( expr, &expr->u.subtree[1], op2 ); } else { /* 1 || X => 1 */ return pruneExpr( expr, &expr->u.subtree[0], op1 ); } break; case CO_COMMA: /* c , X => X */ // DbgVerify( ! has_decoration, "FoldBinary -- bad comma" ); expr->u.subtree[1] = NULL; op2 = PTreeCopySrcLocation( op2, expr ); NodeFreeDupedExpr( expr ); return( op2 ); case CO_QUESTION: DbgVerify( ! has_decoration, "FoldBinary -- bad ?" ); op_t = op2->u.subtree[0]; op_f = op2->u.subtree[1]; has_decoration = isCondDecor( op_t ); DbgVerify( has_decoration == isCondDecor( op_f ) , "FoldBinary -- bad ?:" ); if( has_decoration ) { op_t = op_t->u.subtree[1]; op_f = op_f->u.subtree[1]; } if( ! zeroConstant( op1 ) ) { /* 1 ? T : F => T */ if( has_decoration ) { op2->u.subtree[0]->u.subtree[1] = NULL; } else { op2->u.subtree[0] = NULL; } op2 = op_t; } else { /* 0 ? T : F => F */ if( has_decoration ) { op2->u.subtree[1]->u.subtree[1] = NULL; } else { op2->u.subtree[1] = NULL; } op2 = op_f; } op2 = PTreeCopySrcLocation( op2, expr ); NodeFreeDupedExpr( expr ); return( op2 ); } } else { typ1 = op1->op; typ2 = op2->op; if( ! isIntFloatOp( typ1 ) || ! isIntFloatOp( typ2 ) ) { // (void)0 can make it here return expr; } if( typ1 != typ2 ) { if( PT_FLOATING_CONSTANT == typ1 ) { if( NULL == Integral64Type( op2->type ) ) { if( SignedIntType( op2->type ) ) { op2->u.floating_constant = BFCnvIF( op2->u.int_constant ); } else { op2->u.floating_constant = BFCnvUF( op2->u.uint_constant ); } } else { if( SignedIntType( op2->type ) ) { op2->u.floating_constant = BFCnvI64F( op2->u.int64_constant ); } else { op2->u.floating_constant = BFCnvU64F( op2->u.int64_constant ); } } typ2 = PT_FLOATING_CONSTANT; op2->op = typ2; } else { if( NULL == Integral64Type( op1->type ) ) { if( SignedIntType( op1->type ) ) { op1->u.floating_constant = BFCnvIF( op1->u.int_constant ); } else { op1->u.floating_constant = BFCnvUF( op1->u.uint_constant ); } } else { if( SignedIntType( op1->type ) ) { op1->u.floating_constant = BFCnvI64F( op1->u.int64_constant ); } else { op1->u.floating_constant = BFCnvU64F( op1->u.int64_constant ); } } typ1 = PT_FLOATING_CONSTANT; op1->op = typ2; } } if( PT_FLOATING_CONSTANT == typ1 ) { op1 = foldFloating( expr->cgop, op1, op2->u.floating_constant ); } else if( SignedIntType( op1->type ) ) { if( NULL == Integral64Type( op1->type ) && NULL == Integral64Type( op2->type ) ) { op1 = foldInt( expr->cgop, op1, op2->u.int_constant ); } else { op1 = foldInt64( expr->cgop, op1, op2->u.int64_constant ); } } else { if( NULL == Integral64Type( op1->type ) && NULL == Integral64Type( op2->type ) ) { op1 = foldUInt( expr->cgop, op1, op2->u.uint_constant ); } else { op1 = foldUInt64( expr->cgop, op1, op2->u.int64_constant ); } } if( op1 != NULL ) { /* binary op was folded! */ if( has_decoration ) { orig1->u.subtree[1] = NULL; orig2->u.subtree[1] = NULL; } else { expr->u.subtree[0] = NULL; } op1 = castConstant( op1, type, &cast_happened ); op1 = PTreeCopySrcLocation( op1, expr ); NodeFreeDupedExpr( expr ); return op1; } } return( expr ); }
PTREE AnalyseCall( // ANALYSIS FOR CALL PTREE expr, // - call expression CALL_DIAG *diagnostic ) // - diagnostics used for function problems { PTREE *r_args; // - reference( arguments ) PTREE *r_func; // - reference( function ) PTREE *ptlist; // - nodes for arguments PTREE left; // - left operand ( the function ) PTREE right; // - right operand ( the arguments ) PTREE this_node; // - node for "this" computation PTREE deref_args; // - member pointer dereference args PTREE last_arg; // - last argument PTREE static_fn_this; // - "this" for a static member PTREE templ_args; // - explicit template arguments SYMBOL sym; // - function symbol SYMBOL caller_sym; // - function that is doing the call TYPE type; // - temporary type TYPE fn_type; // - function type type_flag fn_mod; // - function modifier flags unsigned count; // - # args, caller arg_list *alist; // - arg_list for caller intrinsic_mapping *intr_map;// - mapping for intrinsic function SEARCH_RESULT *result; // - searching result boolean membptr_deref; // - TRUE ==> member pointer dereference boolean has_ellipsis; // - TRUE ==> ellipsis in argument list boolean virtual_call; // - TRUE ==> virtual call TEMP_PT_LIST default_list; // - default PTREE list TEMP_ARG_LIST default_args; // - default arg_list FNOV_DIAG fnov_diag; // - diagnosis information; r_args = PTreeRefRight( expr ); last_arg = *r_args; right = NodeReverseArgs( &count, last_arg ); *r_args = right; r_func = PTreeRefLeft( expr ); left = *r_func; membptr_deref = FALSE; this_node = NULL; intr_map = NULL; static_fn_this = NULL; virtual_call = FALSE; switch( left->cgop ) { case CO_DOT: case CO_ARROW: this_node = left->u.subtree[0]; left->u.subtree[0] = NULL; left = NodePruneTop( left ); *r_func = left; r_func = PTreeRefLeft( expr ); left = *r_func; if( ( left->op == PT_ID ) && ( left->cgop == CO_NAME_DTOR ) ) { /* dtor of a non-class type */ left = NodePruneTop( *r_func ); /* NYI: verify dtor call has no arguments */ expr->u.subtree[0] = NULL; NodeFreeDupedExpr( expr ); expr = NodeConvert( GetBasicType( TYP_VOID ), this_node ); expr = NodeComma( expr, left ); return( expr ); } break; case CO_CALL_EXEC_IND: if( left->flags & PTF_CALLED_ONLY ) { /* member pointer dereference being called */ deref_args = left->u.subtree[1]; this_node = NodeDupExpr( &(deref_args->u.subtree[1]) ); membptr_deref = TRUE; } break; } alist = ArgListTempAlloc( &default_args, count ); ptlist = PtListAlloc( default_list, count ); NodeBuildArgList( alist, ptlist, right, count ); if( this_node == NULL ) { alist->qualifier = FunctionThisQualifier(); } else { alist->qualifier = BaseTypeClassFlags( NodeType( this_node ) ); } if( NodeIsBinaryOp( left, CO_TEMPLATE ) ) { DbgAssert( left->u.subtree[0]->op == PT_SYMBOL ); templ_args = left->u.subtree[1]; left->u.subtree[1] = NULL; left = NodePruneTop( left ); *r_func = left; r_func = PTreeRefLeft( expr ); left = *r_func; } else { templ_args = NULL; } if( left->op == PT_SYMBOL ) { FNOV_RESULT ovret; SYMBOL orig; // - original symbol sym = left->u.symcg.symbol; orig = sym; if( left->cgop == CO_NAME_CONVERT ) { ovret = UdcOverloadedDiag( &sym , left->u.symcg.result , sym , SymFuncReturnType( sym ) , alist->qualifier , &fnov_diag ); } else { ovret = FuncOverloadedDiag( &sym , left->u.symcg.result , sym , alist , ptlist , templ_args , &fnov_diag ); } switch( ovret ) { case FNOV_AMBIGUOUS : CallDiagAmbiguous( expr, diagnostic->msg_ambiguous, &fnov_diag ); NodeFreeDupedExpr( this_node ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); return( expr ); case FNOV_NO_MATCH : if( this_node == NULL ) { if( SymIsThisFuncMember( orig ) ) { this_node = NodeThisCopyLocation( left ); } } if( this_node != NULL ) { if( ( ! SymIsCtor( orig ) ) &&( ! SymIsDtor( orig ) ) &&( CNV_OK != AnalysePtrCV ( this_node , TypeThisSymbol( orig , this_node->flags & PTF_LVALUE ) , NodeType( this_node ) , CNV_FUNC_THIS ) ) ) { PTreeErrorNode( expr ); InfSymbolDeclaration( orig ); NodeFreeDupedExpr( this_node ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); return( expr ); } } CallDiagNoMatch( expr , diagnostic->msg_no_match_one , diagnostic->msg_no_match_many , this_node , orig , &fnov_diag ); NodeFreeDupedExpr( this_node ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); return( expr ); } FnovFreeDiag( &fnov_diag ); left->u.symcg.symbol = sym; result = left->u.symcg.result; if( this_node == NULL ) { if( SymIsThisFuncMember( sym ) ) { if( result->use_this ) { this_node = NodeThisCopyLocation( left ); if( this_node == NULL ) { PTreeErrorExpr( expr, ERR_INVALID_NONSTATIC_ACCESS ); InfSymbolDeclaration( sym ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); return( expr ); } } else { PTreeErrorExpr( expr, ERR_BARE_FUNCTION_ACCESS ); InfSymbolDeclaration( sym ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); return( expr ); } } } if( ! AnalyseSymbolAccess( expr, left, this_node, &diagAccess ) ) { NodeFreeDupedExpr( this_node ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); return( expr ); } type = sym->sym_type; fn_type = TypeGetActualFlags( type, &fn_mod ); if( fn_type->flag & TF1_INTRINSIC ) { intr_map = intrinsicMapping( sym ); if( intr_map == NULL ) { outputCallTriggeredWarning( expr, sym ); } } if( fn_mod & TF1_FAR16 ) { /* we are calling a far16 function */ caller_sym = ScopeFunctionInProgress(); caller_sym->flag |= SF_FAR16_CALLER; } left->type = type; if( this_node == NULL ) { if( SymIsThisFuncMember( sym ) ) { this_node = NodeThisCopyLocation( left ); } } else { if( SymIsStaticFuncMember( sym ) ) { #ifdef OLD_STATIC_MEMBER_ACCESS NodeFreeDupedExpr( this_node ); #else static_fn_this = this_node; #endif this_node = NULL; } } if( this_node != NULL ) { TYPE pted; pted = TypePointedAtModified( this_node->type ); if( pted == NULL ) { pted = this_node->type; } if( TypeTruncByMemModel( pted ) ) { if( SymIsCtor( sym ) ) { PTreeErrorExpr( this_node, ERR_CTOR_OBJ_MEM_MODEL ); } else if( SymIsDtor( sym ) ) { PTreeErrorExpr( this_node, ERR_DTOR_OBJ_MEM_MODEL ); } else { PTreeErrorExpr( this_node, ERR_THIS_OBJ_MEM_MODEL ); } InfSymbolDeclaration( sym ); PTreeErrorNode( expr ); NodeFreeDupedExpr( this_node ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); NodeFreeDupedExpr( static_fn_this ); return( expr ); } if( adjustForVirtualCall( &this_node, r_func, result ) ) { virtual_call = TRUE; expr->cgop = CO_CALL_EXEC_IND; left = VfunSetupCall( expr->u.subtree[0] ); left = VfnDecorateCall( left, sym ); } else { expr->cgop = CO_CALL_EXEC; left = NodeUnaryCopy( CO_CALL_SETUP, expr->u.subtree[0] ); SymMarkRefed( sym ); } } else { NodeFreeSearchResult( left ); expr->cgop = CO_CALL_EXEC; left = NodeUnaryCopy( CO_CALL_SETUP, expr->u.subtree[0] ); SymMarkRefed( sym ); } } else { if( ! membptr_deref ) { /* i.e, p->foo() where foo is a pointer to a function */ NodeFreeDupedExpr( this_node ); this_node = NULL; } sym = NULL; left = expr->u.subtree[0]; type = TypedefModifierRemove( left->type ); if( type->id == TYP_POINTER ) { type = type->of; } fn_type = TypeGetActualFlags( type, &fn_mod ); if( fn_mod & TF1_FAR16 ) { /* we are calling a far16 function */ caller_sym = ScopeFunctionInProgress(); caller_sym->flag |= SF_FAR16_CALLER; } if( ! TypeHasNumArgs( type, count ) ) { PTreeErrorExpr( expr, ERR_PARM_COUNT_MISMATCH_POINTER ); CErr2p( INF_FUNCTION_TYPE, type ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); NodeFreeDupedExpr( static_fn_this ); return( expr ); } expr->cgop = CO_CALL_EXEC_IND; left = VfunSetupCall( left ); } expr->u.subtree[0] = left; #if _CPU == _AXP if( intr_map != NULL && intr_map->cgop == CO_VASTART ) { expr = convertVaStart( expr, alist, type ); } else { expr = NodeConvertCallArgList( expr, count, type, &expr->u.subtree[1] ); } #else expr = NodeConvertCallArgList( expr, count, type, &expr->u.subtree[1] ); #endif if( expr->op != PT_ERROR ) { TYPE ftype; // - function type PTREE cdtor; // - CDTOR node PTREE callnode; // - call node PTREE retnnode; // - return node (for struct return) callnode = expr; if( this_node == NULL ) { cdtor = NULL; } else { this_node = NodeArg( this_node ); if( virtual_call ) { this_node->flags |= PTF_ARG_THIS_VFUN; } if( sym != NULL && SymIsDtor( sym ) ) { cdtor = NodeArg( NodeCDtorArg( DTOR_NULL ) ); } else { cdtor = NULL; } } ftype = type; type = TypedefModifierRemove( type ); has_ellipsis = TypeHasEllipsisArg( type ); type = type->of; { TYPE tgt = TypeReference( type ); if( tgt == NULL ) { expr->type = type; } else { expr->type = tgt; expr->flags |= PTF_LVALUE; } } if( sym != NULL ) { if( ! AddDefaultArgs( sym, expr ) ) { NodeFreeDupedExpr( cdtor ); NodeFreeDupedExpr( this_node ); ArgListTempFree( alist, count ); PtListFree( ptlist, count ); return expr; } } if( NULL != TypeReference( type ) ) { expr->flags |= PTF_LVALUE; } if( OMR_CLASS_REF == ObjModelArgument( type ) ) { retnnode = NodeTemporary( type ); retnnode = PTreeCopySrcLocation( retnnode, expr ); } else { retnnode = NULL; } expr = CallArgsArrange( ftype , callnode , callnode->u.subtree[1] , this_node , cdtor , retnnode ); if( retnnode != NULL ) { expr = NodeDtorExpr( expr, retnnode->u.symcg.symbol ); if( SymRequiresDtoring( retnnode->u.symcg.symbol ) ) { expr = PtdCtoredExprType( expr, NULL, type ); } } type = StructType( type ); if( type != NULL && ! TypeDefined( type ) ) { PTreeErrorExpr( expr, ERR_RETURN_UNDEFD_TYPE ); } if( intr_map != NULL && expr->op != PT_ERROR ) { #if _CPU == _AXP if( intr_map->cgop == CO_VASTART ) { expr = transformVaStart( expr ); } else { expr = PTreeIntrinsicOperator( expr, intr_map->cgop ); } #else expr = PTreeIntrinsicOperator( expr, intr_map->cgop ); #endif expr->flags |= PTF_MEANINGFUL | PTF_SIDE_EFF; } } if( static_fn_this != NULL ) { expr = NodeCommaIfSideEffect( static_fn_this, expr ); } ArgListTempFree( alist, count ); PtListFree( ptlist, count ); return expr; }