void UdcDiagNoMatch( // DIAGNOSE NO MATCHES FOR UDC LOOKUP PTREE src, // - ctor expression TYPE tgt_type, // - target type unsigned msg_none, // - message: no UDC's unsigned msg_many, // - message: many functions FNOV_DIAG *fnov_diag ) // - overload diagnosis information { SYMBOL orig; DIAG_INFO diag; diag.bad_src = NodeType( src ); diag.bad_tgt = tgt_type; switch( fnov_diag->num_candidates ) { case 0 : PTreeErrorExpr( src, msg_none ); break; case 1 : orig = FnovNextRejectEntry( fnov_diag ); if( orig == NULL ) { /* no fns matched at all but there happened to be one */ PTreeErrorExpr( src, msg_none ); } else { diag.bad_fn = NULL; diag.bad_parm = 1; PTreeExtractLocn( src, &diag.location ); displayDiagInfo( &diag, msg_none, src, orig ); } break; default : CallDiagnoseRejects( src, msg_many, fnov_diag ); ConversionTypesSet( diag.bad_src, diag.bad_tgt ); ConversionDiagnoseInf(); break; } }
static bool throwCnvFront( // GET FRONT-END INFO. FOR THROW TYPE TYPE type, // - type to be thrown PTREE expr ) // - expression for errors { bool ret; // - return value THROW_CNV_CTL ctl; // - control information PTreeExtractLocn( expr, &ctl.err_locn ); ThrowCnvInit( &ctl, type ); ret = ! ctl.error_occurred; ThrowCnvFini( &ctl ); return ret; }
static void buildDiagInfo( // BUILD DIAG_INFO FOR ARGUMENT DIAG_INFO *diag, // - diagnostic information PTREE arg, // - expression for argument int bad_parm, // - index of erroneous parameter SYMBOL fun ) // - function for argument { arg_list* alist; // - function args unsigned num_args; // - # args diag->bad_parm = bad_parm + 1; alist = SymFuncArgList( fun ); num_args = alist->num_args; if( bad_parm >= num_args ) { TYPE last_arg = alist->type_list[ num_args - 1 ]; if( last_arg->id == TYP_DOT_DOT_DOT ) { diag->bad_tgt = last_arg; } else { diag->bad_tgt = NULL; } } else { diag->bad_tgt = alist->type_list[ bad_parm ]; } PTreeExtractLocn( arg, &diag->location ); if( PointerToFuncEquivalent( arg->type ) ) { PTREE operand; // - argument operand operand = arg; if( NodeIsUnaryOp( operand, CO_ADDR_OF ) ) { operand = PTreeOpLeft( operand ); } if( operand->op == PT_SYMBOL ) { diag->bad_fn = operand->u.symcg.symbol; if( IsActualOverloadedFunc( diag->bad_fn , operand->u.symcg.result ) ) { diag->bad_src = NULL; } else { diag->bad_fn = NULL; diag->bad_src = NodeType( arg ); } } else { diag->bad_fn = NULL; diag->bad_src = NodeType( arg ); } } else { diag->bad_fn = NULL; diag->bad_src = NodeType( arg ); } }
static PTREE DynamicCastVoid // DYNAMIC CAST CODE: VOID * ( CONVCTL* ctl ) // - conversion information { PTREE expr; // - cast expression PTREE from; // - type being case from TOKEN_LOCN locn; // - cast location CLASSINFO *info; // - source (or base class of source) class info expr = ctl->expr; expr = PTreeExtractLocn( expr, &locn ); expr = NodePruneLeftTop( expr ); expr->locn = locn; from = NodeTypeid( ctl->src.pted ); info = GetWithinOffsetOfVFPtr( ctl->src.pted, &expr ); expr = NodeArguments( from , NodeOffset( info->vf_offset ) , expr , NULL ); expr = RunTimeCall( expr, ctl->tgt.orig , RTF_DYN_CAST_VOID ); return( expr ); }
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; }
PTREE DynamicCast // DYNAMIC CAST CODE ( CONVCTL* ctl ) // - conversion information { PTREE expr; // - cast expression TOKEN_LOCN locn; // - cast location PTREE from; // - type being cast from PTREE to; // - type being cast to CLASSINFO *info; // - source (or base class of source) class info if( ctl->tgt.pted->id == TYP_VOID ) { return( DynamicCastVoid( ctl ) ); } else { expr = ctl->expr; expr = PTreeExtractLocn( expr, &locn ); expr = NodePruneLeftTop( expr ); expr->locn = locn; from = NodeTypeid( ctl->src.pted ); to = NodeTypeid( ctl->tgt.pted ); info = GetWithinOffsetOfVFPtr( ctl->src.pted, &expr ); expr = NodeArguments( to , from , NodeOffset( info->vf_offset ) , expr , NULL ); DbgAssert( ctl->src.reference == ctl->tgt.reference ); if( ctl->src.reference && ctl->tgt.reference ) { // ref => ref expr = RunTimeCall( expr, ctl->tgt.orig, RTF_DYN_CAST_REF ); } else { // ptr => ptr DbgAssert( !ctl->src.reference && !ctl->tgt.reference ); expr = RunTimeCall( expr, ctl->tgt.orig , RTF_DYN_CAST_PTR ); } } return( expr ); }