static PTREE genVfunCall( // DIRECTLY GENERATE VFUN CALL target_offset_t vf_offset, // - offset to VF table ptr PTREE node, // - original "this" expression target_offset_t vf_index, // - index into VF table SYMBOL sym ) // - symbol to access { TYPE vfptr_type; // - type[ ptr to VF table ] TYPE vfn_type; // - type[ ptr to VF ] node = NodeBinary( CO_DOT, node, NodeOffset( vf_offset ) ); vfptr_type = MakeVFTableFieldType( TRUE ); node->type = vfptr_type; node->flags |= PTF_LVALUE; node = PtdExprConst( node ); node = NodeRvalue( node ); vfn_type = TypePointedAtModified( vfptr_type ); node = NodeBinary( CO_DOT , node , NodeOffset( vf_index * CgMemorySize( vfn_type ) ) ); node->type = vfn_type; node->flags |= PTF_LVALUE; node = NodeRvalue( node ); node->type = sym->sym_type; return node; }
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 ); }
TYPE TypeFunctionCalled( // GET FUNCTION DECLARATION TYPE CALLED TYPE type ) // - function type called { TYPE pted; // - NULL or type pointed at type = TypeReferenced( type ); pted = TypePointedAtModified( type ); if( NULL != pted ) { type = pted; } return( FunctionDeclarationType( type ) ); }
TYPE TypeConvertFromPcPtr( // TRANSFORM TYPE AFTER CONVERSION FROM PC PTR TYPE ptype ) // - pointer type { type_flag flags; // - flags for item pointed at TYPE pted; // - type pointed at (modified) TYPE type; // - type pointed at (unmodified) SYMBOL baser; // - basing infomation pted = TypePointedAtModified( ptype ); type = TypeModExtract( pted, &flags, &baser, TC1_NOT_ENUM_CHAR ); switch( flags & TF1_BASED ) { case 0 : if( flags & TF1_FAR16 ) { ptype = TypeRebuildPcPtr( type, flags, DefaultMemoryFlag( type ) ); } break; case TF1_BASED_VOID : ptype = TypeRebuildPcPtr( type, flags, TF1_NEAR ); break; case TF1_BASED_ADD : { type_flag bflags; // - flags for baser TypePointedAt( baser->sym_type, &bflags ); ptype = TypeRebuildPcPtr( type, flags, bflags & TF1_MEM_MODEL ); } break; case TF1_BASED_SELF : ptype = TypeRebuildPcPtr( type, flags, TF1_FAR ); break; case TF1_BASED_FETCH : ptype = TypeRebuildPcPtr( type, flags, TF1_FAR ); break; case TF1_BASED_STRING : ptype = TypeRebuildPcPtr( type, flags, TF1_FAR ); break; } return( ptype ); }
bool PtrCnvInfo( // FILL IN PTR-CONVERSION INFORMATION TYPE ptr_src, // - source type TYPE ptr_tgt, // - target pointer type PTRCNV* info ) // - pointer-conversion information { bool ok; // - return: true ==> can convert trivially bool first_level; // - true ==> at first level bool const_always; // - true ==> const on all preceding levels TYPE orig_src; // - original src type info->converts = false; info->to_base = false; info->to_derived = false; info->to_void = false; info->ptr_integral_ext = false; info->cv_err_0 = false; info->reint_cast_ok = false; orig_src = ptr_src; ptr_src = TypePointedAtModified( ptr_src ); ptr_tgt = TypePointedAtModified( ptr_tgt ); if( ptr_src == NULL ) { info->pted_src = NULL; info->flags_src = 0; ptr_tgt = TypeGetActualFlags( ptr_tgt, &info->flags_tgt ); info->pted_tgt = ptr_tgt; if( ptr_tgt->id == TYP_VOID ) { info->to_void = true; } if( NULL != orig_src && IntegralType( orig_src ) ) { info->reint_cast_ok = true; } ok = false; } else { first_level = true; const_always = true; info->reint_cast_ok = true; for( ; ; ) { type_flag flags_src; // source flags type_flag flags_tgt; // target flags type_flag cv_src; // source CV flags type_flag cv_tgt; // target CV flags ptr_src = TypeGetActualFlags( ptr_src, &flags_src ); ptr_tgt = TypeGetActualFlags( ptr_tgt, &flags_tgt ); cv_src = flags_src & TF1_CV_MASK; cv_tgt = flags_tgt & TF1_CV_MASK; if( cv_src != ( cv_tgt & cv_src ) ) { // test cv-containment if( first_level ) { info->cv_err_0 = true; // - diagnose elsewhere } else { ok = false; break; } } if( first_level ) { TYPE cl_src; // class for source TYPE cl_tgt; // class for target ok = true; info->pted_src = ptr_src; info->pted_tgt = ptr_tgt; info->flags_src = flags_src; info->flags_tgt = flags_tgt; cl_src = StructType( ptr_src ); if( ptr_tgt->id == TYP_VOID ) { info->to_void = true; // ok = (ptr_src == TYP_VOID); // break; } else if( NULL != cl_src ) { cl_tgt = StructType( ptr_tgt ); if( NULL != cl_tgt && cl_tgt != cl_src ) { if( TypeDerived( ptr_src, ptr_tgt ) ) { info->to_base = true; ok = false; // break; } else if( TypeDerived( ptr_tgt, ptr_src ) ) { info->to_derived = true; ok = false; // break; } } } else if( ( ptr_src->id != ptr_tgt->id ) && IntegralType( ptr_src ) && IntegralType( ptr_tgt ) && ( CgMemorySize( ptr_src ) == CgMemorySize( ptr_tgt ) ) ) { info->ptr_integral_ext = true; } if( !ok ) { if( info->cv_err_0 ) { info->reint_cast_ok = false; } break; } first_level = false; } if( cv_tgt != cv_src ) { // test const'ed to here if( ! const_always ) { info->reint_cast_ok = false; ok = false; break; } } if( (cv_tgt & TF1_CONST) == 0 ) { const_always = false; } if( ptr_src == ptr_tgt ) { ok = true; break; } if( TYP_FUNCTION == ptr_src->id || TYP_FUNCTION == ptr_tgt->id ) { ok = TypeCompareExclude( ptr_src , ptr_tgt , TC1_FUN_LINKAGE | TC1_NOT_ENUM_CHAR ); break; } ptr_src = TypePointedAtModified( ptr_src ); ptr_tgt = TypePointedAtModified( ptr_tgt ); if( NULL == ptr_src ) { if( NULL != ptr_tgt && NULL != FunctionDeclarationType( ptr_tgt ) ) { info->reint_cast_ok = false; } ok = false; break; } if( NULL == ptr_tgt ) { ok = false; break; } } } return( ok ); }
CNV_RETN PtrConvertCommon( // CONVERT TO COMMON PTR PTREE expr ) // - expression { PTREE *r_left; // - reference( left node ) PTREE *r_right; // - reference( right node ) TYPE ltype; // - type on left TYPE rtype; // - type on right TYPE lptype; // - new ptr type on left TYPE rptype; // - new ptr type on right TYPE lbtype; // - base type on left TYPE rbtype; // - base type on right TYPE type; // - resultant type TYPE common; // - common base type CNV_RETN retn; // - conversion return r_left = &expr->u.subtree[0]; ltype = NodeType( *r_left ); r_right = &expr->u.subtree[1]; rtype = NodeType( *r_right ); if( same_ptr_types( ltype, rtype ) ) { type = ltype; if( CgTypeSize( ltype ) > CgTypeSize( rtype ) ) { expr->type = ltype; } else { expr->type = rtype; } retn = propogateNonZero( CNV_OK, expr ); } else if( ptr_to_void( ltype ) ) { retn = NodeCheckCnvPtrVoid( &expr, rtype, ltype ); retn = check_common( retn, expr, ltype ); } else if( ptr_to_void( rtype ) ) { retn = NodeCheckCnvPtrVoid( &expr, ltype, rtype ); retn = check_common( retn, expr, rtype ); } else{ lbtype = TypePointedAtModified( ltype ); rbtype = TypePointedAtModified( rtype ); switch( TypeCommonDerivation( lbtype, rbtype ) ) { case CTD_LEFT : case CTD_LEFT_VIRTUAL : retn = NodeConvertPtr( CNVPTR_DERIVED_ONLY, r_left, ltype, rtype ); retn = check_common( retn, expr, rtype ); break; case CTD_RIGHT : case CTD_RIGHT_VIRTUAL : retn = NodeConvertPtr( CNVPTR_DERIVED_ONLY, r_right, rtype, ltype ); retn = check_common( retn, expr, ltype ); break; case CTD_NO : common = TypeCommonBase( rbtype, lbtype ); if( common != NULL ) { lptype = TypePointedAtReplace( ltype, common ); rptype = TypePointedAtReplace( rtype, common ); /* TypeCommonBase verified everything so these convs will work*/ NodeConvertPtr( CNVPTR_DERIVED_ONLY, r_left, ltype, lptype ); NodeConvertPtr( CNVPTR_DERIVED_ONLY, r_right, rtype, rptype); expr->type = expr->u.subtree[0]->type; retn = propogateNonZero( CNV_OK, expr ); } else { retn = UserDefCnvToType( r_left, ltype, rtype ); if( retn == CNV_IMPOSSIBLE ) { retn = UserDefCnvToType( r_right, rtype, ltype ); retn = check_common( retn, expr, ltype ); } else { retn = check_common( retn, expr, rtype ); } } break; case CTD_RIGHT_AMBIGUOUS : ConversionTypesSet( rtype, ltype ); case CTD_LEFT_AMBIGUOUS : retn = CNV_AMBIGUOUS; break; case CTD_RIGHT_PRIVATE : ConversionTypesSet( rtype, ltype ); case CTD_LEFT_PRIVATE : retn = CNV_PRIVATE; break; case CTD_RIGHT_PROTECTED : ConversionTypesSet( rtype, ltype ); case CTD_LEFT_PROTECTED : retn = CNV_PROTECTED; break; } } return( retn ); }
CNV_RETN NodeConvertPtr( // CONVERT A POINTER CNVPTR_REQD reqd_cnvptr, // - type of conversion PTREE *expr, // - expression to be converted TYPE src, // - source type (converted from) TYPE tgt ) // - target type (converted to) { SCOPE src_scope; // - source scope SCOPE tgt_scope; // - target scope CNV_RETN retn = CNV_ERR; // - return: CNV_... indicates what happened if( same_ptr_types( src, tgt ) ) { (*expr)->type = src; return( CNV_OK ); } src_scope = scope_for_ptr( src ); tgt_scope = scope_for_ptr( tgt ); switch( TypeCommonDerivation( TypePointedAtModified( src ) , TypePointedAtModified( tgt ) ) ) { case CTD_NO : if( ptr_to_void( tgt ) ) { *expr = NodeConvert( tgt, *expr ); retn = check_result_cv( expr, src, tgt, reqd_cnvptr ); } else { retn = CNV_IMPOSSIBLE; } break; case CTD_RIGHT_PROTECTED : if( (reqd_cnvptr & CNVPTR_CAST) == 0 ) { if( reqd_cnvptr & CNVPTR_VIRT_TO_DERIVED ) { retn = CNV_PROTECTED; } else { retn = CNV_IMPOSSIBLE; } break; } /* fall through */ case CTD_RIGHT_PRIVATE : if( (reqd_cnvptr & CNVPTR_CAST) == 0 ) { if( reqd_cnvptr & CNVPTR_VIRT_TO_DERIVED ) { retn = CNV_PRIVATE; } else { retn = CNV_IMPOSSIBLE; } break; } /* fall through */ case CTD_RIGHT : if( reqd_cnvptr & CNVPTR_VIRT_TO_DERIVED ) { NodeConvertBaseToDerived( expr, tgt, tgt_scope, src_scope ); retn = check_result_cv( expr, src, tgt, reqd_cnvptr ); } else { retn = CNV_IMPOSSIBLE; } break; case CTD_RIGHT_VIRTUAL : if( reqd_cnvptr & CNVPTR_VIRT_TO_DERIVED ) { retn = CNV_VIRT_DER; } else { retn = CNV_IMPOSSIBLE; } break; case CTD_RIGHT_AMBIGUOUS : if( reqd_cnvptr & CNVPTR_VIRT_TO_DERIVED ) { retn = CNV_AMBIGUOUS; } else { retn = CNV_IMPOSSIBLE; } break; case CTD_LEFT_PRIVATE : if( (reqd_cnvptr & CNVPTR_CAST) == 0 ) { retn = CNV_PRIVATE; break; } /* fall through */ case CTD_LEFT_PROTECTED : if( (reqd_cnvptr & CNVPTR_CAST) == 0 ) { retn = CNV_PROTECTED; break; } /* fall through */ case CTD_LEFT : NodeConvertDerivedToBase( expr, tgt, src_scope, tgt_scope ); retn = check_result_cv( expr, src, tgt, reqd_cnvptr ); break; case CTD_LEFT_VIRTUAL : NodeConvertDerivedToVirt( expr, tgt, src_scope, tgt_scope ); retn = check_result_cv( expr, src, tgt, reqd_cnvptr ); break; case CTD_LEFT_AMBIGUOUS : retn = CNV_AMBIGUOUS; break; } return( retn ); }
TYPE_SIG *TypeSigFind( // FIND TYPE SIGNATURE TYPE_SIG_ACCESS acc, // - access type TYPE type, // - type for signature TOKEN_LOCN* err_locn, // - error location for access errors bool *error_occurred ) // - to set error indication { TYPE_SIG *srch; // - signature for searching TYPE_SIG *sig; // - signature SYMBOL sym; // - symbol unsigned size; // - size of R/O data NAME typesig_name; // - name of type signature TYPE typesig_type; // - type of type signature bool err_this_time; // - true ==> we have error TYPE_SIG_ACCESS acc_ind; // - indirect access err_this_time = false; type = TypeCanonicalThr( type ); sig = NULL; RingIterBeg( type_sigs, srch ) { if( TypesSameExclude( srch->type, type, TC1_NOT_ENUM_CHAR ) ) { sig = srch; break; } } RingIterEnd( srch ); if( sig == NULL ) { THROBJ thr; // - category of object DbgVerify( 0 == ( acc & TSA_GEN ) , "TypeSigFind -- no type signature & TSA_GEN" ); sig = RingCarveAlloc( carveTYPE_SIG, &type_sigs ); sig->type = type; sig->default_ctor = NULL; sig->copy_ctor = NULL; sig->dtor = NULL; sig->sym = NULL; sig->base = NULL; sig->cgref = false; sig->cggen = false; sig->free = false; thr = ThrowCategory( type ); if( acc & TSA_INDIRECT ) { acc_ind = acc | TSA_INDIRECT_ACCESS; } else if( acc & TSA_INDIRECT_ACCESS ) { acc_ind = ( acc & ~ TSA_INDIRECT ) | TSA_INDIRECT_GEN; } else { acc_ind = acc; } size = 0; switch( thr ) { case THROBJ_PTR_SCALAR : case THROBJ_PTR_CLASS : sig->base = TypeSigFind( acc_ind & TSA_INDIRECT , TypePointedAtModified( type ) , err_locn , &err_this_time ); size = typeSigHdrSize(); break; case THROBJ_SCALAR : case THROBJ_PTR_FUN : case THROBJ_VOID_STAR : size = typeSigHdrSize() + SizeTargetSizeT(); break; case THROBJ_REFERENCE : sig->base = TypeSigFind( acc_ind , TypeReference( type ) , err_locn , &err_this_time ); break; case THROBJ_CLASS : case THROBJ_CLASS_VIRT : size = 3 * CgCodePtrSize() + CgDataPtrSize() + typeSigHdrSize(); break; case THROBJ_ANYTHING : break; default : DbgStmt( CFatal( "cgTypeSignature -- invalid throw category" ) ); } size += typeSigNameSize( thr ); if( size == 0 ) { sym = NULL; } else { // - type for TYPE SIGNATURE variable typesig_name = CppNameTypeSig( type ); sym = ScopeAlreadyExists( GetFileScope(), typesig_name ); if( sym == NULL ) { typesig_type = MakeInternalType( size ); typesig_type = MakeCompilerConstCommonData( typesig_type ); sym = SymCreateFileScope( typesig_type , SC_PUBLIC , SF_REFERENCED | SF_ADDR_TAKEN , typesig_name ); LinkageSet( sym, "C++" ); CgSegId( sym ); } } sig->sym = sym; } if( err_this_time ) { *error_occurred = true; } else { if( NULL != sig->sym ) { SegmentMarkUsed( sig->sym->segid ); } *error_occurred = false; typeSigAccess( acc, sig, err_locn, error_occurred ); } return( sig ); }
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; }