TYPE UdcFindType // FIND TARGET TYPE FOR UDCF ( TYPE src // - source class or reference to it , TYPE tgt ) // - target type { TYPE result; // - result type FNOV_COARSE_RANK rank; // - UDC RANKING bool is_ctor; // - true ==> ctor udc, false ==> udcf udc FNOV_LIST* fnov_list; // - matches list FNOV_DIAG diag; // - lookup diagnosis if( NULL == ClassTypeForType( src ) ) { result = NULL; } else { rank = UdcLocate( FNOV_UDC_COPY , src , tgt , NULL , &is_ctor , &fnov_list , &diag ); if( rank == OV_RANK_UD_CONV ) { result = SymFuncReturnType( fnov_list->sym ); } else { result = NULL; } FnovListFree( &fnov_list ); FnovFreeDiag( &diag ); } return result; }
PTREE NodeMakeCall( // FABRICATE A FUNCTION CALL EXPRESSION SYMBOL proc, // - procedure TYPE type, // - return type PTREE args ) // - arguments { DbgVerify( (PointerTypeEquivalent( type ) == NULL) == (PointerTypeEquivalent( SymFuncReturnType( proc ) ) == NULL) , "NodeMakeCall -- return type mismatch" ); return makeCall( NodeMakeCallee( proc ), type, args, TRUE ); }
static SYMBOL getSymInScope( // GET A SYMBOL IN A SCOPE SCOPE scope, // - the scope SYMBOL orig ) // - original symbol { SEARCH_RESULT *result; // - search result for symbol SYMBOL sym; // - the symbol arg_list *alist; // - arguments for function NAME name; // - symbol name name = orig->name->name; alist = SymFuncArgList( orig ); if( name == CppConversionName() ) { result = ScopeFindScopedMemberConversion( scope , scope , SymFuncReturnType( orig ) , alist->qualifier ); if( result == NULL ) { sym = NULL; } else { sym = result->sym; ScopeFreeResult( result ); if( sym != NULL ) { if( SymScope( sym ) != scope ) { sym = NULL; } } } } else { result = ScopeContainsMember( scope, name ); if( result == NULL ) { sym = NULL; } else { sym = result->sym_name->name_syms; // we may have found a type-name, so check for NULL if( sym != NULL && SymIsFunction( sym ) ) { switch( FuncOverloaded( &sym , result , sym , alist , NULL ) ) { case FNOV_NONAMBIGUOUS : break; default : sym = NULL; break; } } else { sym = NULL; } ScopeFreeResult( result ); } } return( sym ); }
void CgRtCallInit( // SET UP A R/T CALL RT_DEF *def, // - definition for call RTF rt_code ) // - code for run/time call { SYMBOL sym; // - symbol for run/time call sym = RunTimeCallSymbol( rt_code ); def->type = CgTypeOutput( SymFuncReturnType( sym ) ); def->handle = CGInitCall( CgSymbol( sym ) , def->type , (cg_sym_handle)sym ); }
PTREE RunTimeCall( // GENERATE A RUN-TIME CALL PARSE SUBTREE PTREE expr, // - expression for operands TYPE type, // - type for function return RTF code ) // - code for function { SYMBOL func; func = RunTimeCallSymbol( code ); DbgVerify( (PointerTypeEquivalent( type ) == NULL) == (PointerTypeEquivalent( SymFuncReturnType( func ) ) == NULL) , "RunTimeCall -- return type mismatch" ); return NodeMakeCall( func, type, expr ); }
// This is kluge because of the lack of a code-generation interface to // signal a virtual function reference. // // This is accomplished by putting out a fake virtual call in dead-code. // void VfnReference( // EMIT VIRTUAL FUNCTION REFERENCE SYMBOL vfun ) // - a virtual function { CGLABEL around; // - label for jump around PTREE fake; // - fake call expression around = CgFrontLabelCs(); CgFrontGotoNear( IC_LABEL_CS, O_GOTO, around ); fake = NodeAssignTemporary( MakePointerTo( vfun->sym_type ) , NodeMakeCallee( vfun ) ); fake = NodeRvalue( fake ); fake = NodeUnaryCopy( CO_CALL_SETUP_IND, fake ); fake = VfnDecorateCall( fake, vfun ); fake = NodeBinary( CO_CALL_EXEC_IND, fake, NULL ); fake->type = SymFuncReturnType( vfun ); fake->flags |= PTF_MEANINGFUL | PTF_SIDE_EFF; fake = NodeDone( fake ); IcEmitExpr( fake ); CgFrontLabdefCs( around ); CgFrontLabfreeCs( 1 ); }
PTREE AnalyseDtorCall( // ANALYSIS FOR SPECIAL DTOR CALLS TYPE class_type, // - class to be destructed PTREE this_node, // - expression for address of class target_offset_t extra ) // - constant for extra second parm { SEARCH_RESULT *result; // - search results SYMBOL dtor_sym; // - DTOR symbol PTREE dtor_id; // - node for dtor symbol PTREE expr; // - expression under construction TYPE return_type; // - type of return boolean virtual_call; // - TRUE ==> virtual dtor TOKEN_LOCN err_locn; // - error location /* assumes class_type->u.c.info->needs_dtor is TRUE */ result = DtorFindResult( class_type ); PTreeExtractLocn( this_node, &err_locn ); ScopeResultErrLocn( result, &err_locn ); dtor_sym = result->sym_name->name_syms; ScopeCheckSymbol( result, dtor_sym ); dtor_id = NodeSymbolCallee( PTreeAlloc(), dtor_sym, result ); virtual_call = adjustForVirtualCall( &this_node, &dtor_id, result ); return_type = SymFuncReturnType( dtor_sym ); expr = makeCall( dtor_id, return_type, NULL, ! virtual_call ); this_node = NodeArg( this_node ); if( virtual_call ) { this_node->flags |= PTF_ARG_THIS_VFUN; } expr = CallArgsArrange( dtor_sym->sym_type , expr , NULL , this_node , NodeArg( NodeCDtorArg( extra ) ) , NULL ); if( virtual_call ) { expr->u.subtree[0] = VfnDecorateCall( expr->u.subtree[0], dtor_sym ); } expr->flags |= PTF_MEANINGFUL | PTF_SIDE_EFF; return expr; }
static void checkAutoReturn( // CHECK IF AUTOMATIC BEING RETURNED PTREE node, // - node to be checked TYPE ret_type ) // - return type { TYPE func_ret; // - type of function return SYMBOL func; // - function called SYMBOL comped; // - function being compiled PTREE expr; // - node for error TYPE refed; // - NULL ==> not reference comped = ScopeFunctionInProgress(); if( SymIsGenedFunc( comped ) ) { return; } expr = node; refed = TypeReference( ret_type ); for( ; ; ) { node = NodeRemoveCastsCommas( node ); if( ( node->op == PT_SYMBOL ) &&( SymIsAutomatic( node->u.symcg.symbol ) ) ) { if( NULL == refed ) { PTreeWarnExpr( expr, WARN_RET_ADDR_OF_AUTO ); } else { PTreeErrorExpr( expr, ERR_RET_AUTO_REF ); } break; } else if( NodeIsBinaryOp( node, CO_DOT ) || NodeIsBinaryOp( node, CO_DOT_STAR ) ) { node = PTreeOpLeft( node ); } else if( NodeIsUnaryOp( node, CO_ADDR_OF ) ) { node = PTreeOpLeft( node ); } else if( NULL != refed ) { if( NodeIsBinaryOp( node, CO_DTOR ) ) { node = PTreeOpRight( node ); } else if( NodeIsBinaryOp( node, CO_CALL_EXEC ) ) { node = PTreeOpLeft( PTreeOpLeft( node ) ); if( node->op == PT_SYMBOL ) { func = node->u.symcg.symbol; if( SymIsCtor( func ) ) { PTreeErrorExpr( expr, ERR_RET_AUTO_REF ); } else { func_ret = SymFuncReturnType( func ); if( NULL != StructType( func_ret ) ) { PTreeErrorExpr( expr, ERR_RET_AUTO_REF ); } } } break; } else if( NodeIsBinaryOp( node, CO_CALL_EXEC_IND ) ) { func_ret = TypeFunctionCalled( NodeFuncForCall( node )->type ); func_ret = func_ret->of; if( NULL != StructType( func_ret ) ) { PTreeErrorExpr( expr, ERR_RET_AUTO_REF ); } break; } else { break; } } else { break; } } }
SYMBOL FormatMsg( VBUF *pbuf, char *fmt, va_list arg ) /****************************************************/ // this function assumes that pbuf is initialized // all information is concatenated to the end of pbuf { VBUF prefix, suffix; char cfmt; char local_buf[ 1 + sizeof( int ) * 2 + 1 ]; unsigned len; SYMBOL retn_symbol; retn_symbol = NULL; cfmt = *fmt; while( cfmt ) { if( cfmt == '%' ) { fmt++; cfmt = *fmt; switch( cfmt ) { case '1': /* %01d */ case '2': /* %02d */ case '3': /* %03d */ case '4': /* %04d */ case '5': /* %05d */ case '6': /* %06d */ case '7': /* %07d */ case '8': /* %08d */ case '9': /* %09d */ len = sticpy( local_buf, va_arg( arg, int ) ) - local_buf; leading( pbuf, '0', ( cfmt - '0' ) - len ); VbufConcStr( pbuf, local_buf ); break; case 'c': /* %c */ VbufConcChr( pbuf, va_arg( arg, int ) ); break; case 's': /* %s */ VbufConcStr( pbuf, va_arg( arg, char * ) ); break; case 'u': /* %u */ VbufConcDecimal( pbuf, va_arg( arg, unsigned int ) ); break; case 'd': /* %d */ VbufConcInteger( pbuf, va_arg( arg, int ) ); break; case 'L': /* token location */ { TOKEN_LOCN *locn; locn = va_arg( arg, TOKEN_LOCN * ); if( locn == NULL ) { VbufConcStr( pbuf, "by compiler" ); } else { char *src_file = SrcFileName( locn->src_file ); if( src_file == NULL ) { VbufConcStr( pbuf, "on the command line" ); } else { if( ( CompFlags.ew_switch_used ) &&( locn->src_file == SrcFileTraceBackFile() ) ) { VbufConcStr( pbuf, "at: " ); } else { VbufConcStr( pbuf, "in: " ); VbufConcStr( pbuf, SrcFileName( locn->src_file ) ); } VbufConcChr( pbuf, '(' ); VbufConcInteger( pbuf, locn->line ); if( locn->column ) { if( CompFlags.ew_switch_used ) { VbufConcChr( pbuf, ',' ); VbufConcInteger( pbuf, locn->column ); } else { VbufConcStr( pbuf, ") (col " ); VbufConcInteger( pbuf, locn->column ); } } VbufConcChr( pbuf, ')' ); } } } break; case 'N': /* name */ FormatName( va_arg( arg, NAME ), &prefix ); VbufConcVbuf( pbuf, &prefix ); VbufFree( &prefix ); break; case 'F': /* symbol name (decorated) */ { SYMBOL sym; sym = va_arg( arg, SYMBOL ); FormatSym( sym, &prefix ); VbufConcVbuf( pbuf, &prefix ); VbufFree( &prefix ); } break; case 'S': /* symbol name (abbreviated) */ { SYMBOL sym; SYMBOL_NAME sn; NAME name; sym = va_arg( arg, SYMBOL ); if( sym == NULL ) { VbufConcStr( pbuf, "module data" ); } else { if( formatClassForSym( sym, pbuf ) ) { VbufConcStr( pbuf, "::" ); } if( SymIsCtor( sym ) ) { formatClassForSym( sym, pbuf ); } else if( SymIsDtor( sym ) ) { VbufConcChr( pbuf, '~' ); formatClassForSym( sym, pbuf ); } else { sn = sym->name; #ifndef NDEBUG if( sn == NULL ) { CFatal( "FormatMsg -- %S symbol has NULL SYMBOL_NAME" ); } #endif name = sn->name; #ifndef NDEBUG if( name == NULL ) { CFatal( "FormatMsg -- %S SYMBOL_NAME has NULL name" ); } #endif if( name == CppConversionName() ) { VbufConcStr( pbuf, "operator " ); FormatType( SymFuncReturnType( sym ) , &prefix , &suffix ); VbufFree( &suffix ); } else { FormatName( name, &prefix ); } VbufConcVbuf( pbuf, &prefix ); VbufFree( &prefix ); } if( sym->flag2 & SF2_TOKEN_LOCN ) { DbgVerify( retn_symbol == NULL, "too many symbols" ); retn_symbol = sym; } } } break; case 'T': /* type name */ { TYPE type = va_arg( arg, TYPE ); TYPE refed = TypeReference( type ); if( NULL != refed ) { type = refed; } FormatType( type, &prefix, &suffix ); VbufConcVbuf( pbuf, &prefix ); VbufConcVbuf( pbuf, &suffix ); VbufFree( &prefix ); VbufFree( &suffix ); VbufTruncWhite( pbuf ); if( NULL != refed ) { VbufConcStr( pbuf, " (lvalue)" ); } } break; case 'P': /* PTREE list */ { const PTREE p = va_arg( arg, PTREE ); FormatPTreeList( p, &prefix ); VbufConcVbuf( pbuf, &prefix ); VbufFree( &prefix ); } break; case 'I': /* PTREE id */ { const PTREE p = va_arg( arg, PTREE ); FormatPTreeId( p, &prefix ); VbufConcVbuf( pbuf, &prefix ); VbufFree( &prefix ); } break; case 'M': /* template info */ { TEMPLATE_INFO * const tinfo = va_arg( arg, TEMPLATE_INFO * ); const SYMBOL sym = tinfo->sym; FormatTemplateInfo( tinfo, &prefix ); VbufConcVbuf( pbuf, &prefix ); VbufFree( &prefix ); if( sym->flag2 & SF2_TOKEN_LOCN ) { DbgVerify( retn_symbol == NULL, "too many symbols" ); retn_symbol = sym; } } break; case 'C': /* template specialisation */ { TEMPLATE_SPECIALIZATION * const tspec = va_arg( arg, TEMPLATE_SPECIALIZATION * ); FormatTemplateSpecialization( tspec, &prefix ); VbufConcVbuf( pbuf, &prefix ); VbufFree( &prefix ); } break; default: VbufConcChr( pbuf, cfmt ); } } else {
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; }