fnovload.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,907 行 · 第 1/5 页
C
1,907 行
} else {
// else they are both references
DbgAssert( base_first != NULL && base_second != NULL );
}
} else if( MemberPtrType( first_type) != NULL &&
MemberPtrType( second_type ) != NULL ) {
// this is intentional
// converting A::* -> B::* is better than A::* to C::*
// so here we're converting from the least derived so the
// longest distance will be to the most derived, the opposite
// of what the test below looks for, so just switch them
base_second = MemberPtrClass( first_type );
base_first = MemberPtrClass( second_type );
}
first_scope = TypeScope( base_first );
second_scope = TypeScope( base_second );
if( first_scope == second_scope ) {
return( OV_CMP_SAME );
}
if( ScopeDerived( first_scope, second_scope ) != DERIVED_NO ) {
return( OV_CMP_BETTER_FIRST );
} else if( ScopeDerived( second_scope, first_scope ) != DERIVED_NO ) {
return( OV_CMP_BETTER_SECOND );
}
return( OV_CMP_SAME );
}
#ifdef NEW_TRIVIAL_RULE
static FNOV_COARSE_RANK equateExactSameTrivial( FNOV_COARSE_RANK result )
/****************************************************************/
// make OV_RANK_SAME and OV_RANK_EXACT the same
{
if( result == OV_RANK_EXACT ) {
result = OV_RANK_TRIVIAL;
}
if( result == OV_RANK_SAME ) {
result = OV_RANK_TRIVIAL;
}
return( result );
}
#else
static FNOV_COARSE_RANK equateExactSame( FNOV_COARSE_RANK result )
/****************************************************************/
// make OV_RANK_SAME and OV_RANK_EXACT the same
{
if( result == OV_RANK_EXACT ) {
result = OV_RANK_SAME;
}
return( result );
}
#endif
static FNOV_COARSE_RANK equateUDCAmbigUDC( FNOV_COARSE_RANK result )
/****************************************************************/
// make OV_RANK_UD_CONV and OV_RANK_UD_CONV_AMBIG the same
// so a class with two UDC is not made unviable, allowing another
// class with only one UDC to be selected
{
if( result == OV_RANK_UD_CONV_AMBIG ) {
result = OV_RANK_UD_CONV;
}
return( result );
}
#ifdef NEW_TRIVIAL_RULE
static OV_RESULT compareArgument( FNOV_RANK *first, TYPE * first_type,
/*********************************************************************/
FNOV_RANK *second, TYPE *second_type )
{
OV_RESULT retn;
FNOV_COARSE_RANK firstrank;
FNOV_COARSE_RANK secondrank;
firstrank = equateExactSameTrivial( first->rank );
secondrank = equateExactSameTrivial( second->rank );
firstrank = equateUDCAmbigUDC( firstrank );
secondrank = equateUDCAmbigUDC( secondrank );
if( firstrank != secondrank ) {
retn = compareInt( firstrank, secondrank );
} else switch( firstrank ) {
case OV_RANK_NO_MATCH:
case OV_RANK_ELLIPSIS:
retn = OV_CMP_SAME;
break;
case OV_RANK_UD_CONV:
retn = compareScalar( &first->u.ud.out
, first_type
, &second->u.ud.out
, second_type, TRUE );
break;
case OV_RANK_STD_CONV_DERIV:
if( ( first_type != NULL ) && ( second_type != NULL ) ) {
retn = compareDerived( *first_type, *second_type );
if( retn != OV_CMP_SAME ) {
break;
}
}
// two target types are not releated
// do the following comparison
case OV_RANK_STD_CONV_VOID:
case OV_RANK_STD_CONV:
case OV_RANK_STD_BOOL:
case OV_RANK_PROMOTION:
case OV_RANK_TRIVIAL:
retn = compareScalar( &first->u.no_ud
, first_type
, &second->u.no_ud
, second_type, FALSE );
break;
case OV_RANK_UD_CONV_AMBIG:
case OV_RANK_SAME:
case OV_RANK_EXACT:
DbgAssert( FALSE ); // made into something else above
break;
DbgDefault( "funny rank\n" );
}
return( retn );
}
#else
static OV_RESULT compareArgument(
/*******************************/
FNOV_RANK *first
, TYPE * first_type
, FNOV_RANK *second
, TYPE *second_type
, FNOV_CONTROL control )
{
OV_RESULT retn;
FNOV_COARSE_RANK firstrank;
FNOV_COARSE_RANK secondrank;
firstrank = equateExactSame( first->rank );
secondrank = equateExactSame( second->rank );
firstrank = equateUDCAmbigUDC( firstrank );
secondrank = equateUDCAmbigUDC( secondrank );
if( firstrank != secondrank ) {
retn = compareInt( firstrank, secondrank );
if( CompFlags.overload_13332 && ( control & FNC_USE_WP13332 ) ) {
if( ( ( firstrank == OV_RANK_SAME )
&& ( secondrank == OV_RANK_TRIVIAL ) )
|| ( ( firstrank == OV_RANK_TRIVIAL )
&& ( secondrank == OV_RANK_SAME ) ) ) {
retn = WP13332( first_type, second_type, retn );
}
}
} else switch( firstrank ) {
case OV_RANK_NO_MATCH:
case OV_RANK_ELLIPSIS:
case OV_RANK_UD_CONV_AMBIG:
retn = OV_CMP_SAME;
break;
case OV_RANK_UD_CONV:
retn = compareScalar( &first->u.ud.out
, first_type
, &second->u.ud.out
, second_type
, TRUE
, control );
break;
case OV_RANK_STD_CONV_DERIV:
if( ( first_type != NULL ) && ( second_type != NULL ) ) {
retn = compareDerived( *first_type, *second_type );
if( retn != OV_CMP_SAME ) {
break;
}
}
// two target types are not releated
// otherwise, do the following comparison
case OV_RANK_STD_CONV_VOID:
case OV_RANK_STD_CONV:
case OV_RANK_STD_BOOL:
case OV_RANK_PROMOTION:
case OV_RANK_TRIVIAL:
retn = compareScalar( &first->u.no_ud
, first_type
, &second->u.no_ud
, second_type
, FALSE
, control);
break;
case OV_RANK_SAME:
case OV_RANK_EXACT:
retn = OV_CMP_SAME;
break;
DbgDefault( "funny rank\n" );
}
return( retn );
}
#endif
static OV_RESULT compareFunction(
/*******************************/
FNOV_LIST *first
, FNOV_LIST *second
, FNOV_CONTROL control )
// compare ranking of first and second
// returns one of:
// OV_CMP_BETTER_FIRST
// OV_CMP_BETTER_SECOND
// OV_CMP_SAME
{
int index;
FNOV_RANK *first_arg;
FNOV_RANK *second_arg;
OV_RESULT result;
OV_RESULT retn;
TYPE *first_type;
TYPE *second_type;
retn = OV_CMP_UNDEFINED;
index = first->num_args;
first_arg = first->rankvector;
second_arg = second->rankvector;
first_type = first->alist->type_list;
second_type = second->alist->type_list;
for(;;) {
if( retn == OV_CMP_SAME ) break;
if( index == 0 ) break;
result = compareArgument( first_arg
, first_type
, second_arg
, second_type
, control );
switch( result ) {
case OV_CMP_BETTER_FIRST:
switch( retn ) {
case OV_CMP_UNDEFINED:
retn = OV_CMP_BETTER_FIRST;
break;
case OV_CMP_BETTER_SECOND:
retn = OV_CMP_SAME;
break;
}
break;
case OV_CMP_BETTER_SECOND:
switch( retn ) {
case OV_CMP_UNDEFINED:
retn = OV_CMP_BETTER_SECOND;
break;
case OV_CMP_BETTER_FIRST:
retn = OV_CMP_SAME;
break;
}
break;
}
index--;
first_arg++;
second_arg++;
first_type++;
second_type++;
}
if( retn == OV_CMP_UNDEFINED ) {
result = compareArgument( &first->thisrank
, NULL
, &second->thisrank
, NULL, FNC_DEFAULT );
switch( result ) {
case OV_CMP_BETTER_FIRST:
retn = OV_CMP_BETTER_FIRST;
break;
case OV_CMP_BETTER_SECOND:
retn = OV_CMP_BETTER_SECOND;
break;
default:
retn = OV_CMP_SAME;
break;
}
}
return( retn );
}
static boolean isRank( FNOV_LIST *entry, FNOV_COARSE_RANK level )
/***************************************************************/
// see if rank of entry is all <= level
// if so, return TRUE, else FALSE
{
int index;
FNOV_RANK *rank;
boolean retn;
retn = TRUE;
rank = entry->rankvector;
index = entry->num_args;
for(;;) {
if( !retn ) break;
if( index == 0 ) break;
retn = ( rank->rank <= level );
index--;
rank++;
}
if( retn ) {
retn = ( entry->thisrank.rank <= level );
}
return( retn );
}
static void setRank( FNOV_LIST *entry, FNOV_COARSE_RANK level )
/*************************************************************/
// make rank = level
{
int index;
FNOV_RANK *rank;
rank = entry->rankvector;
index = entry->num_args;
for(;;) {
if( index == 0 ) break;
rank->rank = level;
index--;
rank++;
}
entry->thisrank.rank = level;
}
static boolean isReturnIdentical( TYPE sym1, TYPE sym2 )
/******************************************************/
// see if two functions have indentical return types
{
boolean retn;
retn = TypesSameExclude( FunctionDeclarationType( sym1 )->of
, FunctionDeclarationType( sym2 )->of
, TC1_NOT_ENUM_CHAR );
return( retn );
}
static void doComputeArgRank( SYMBOL sym, TYPE src, TYPE tgt, PTREE *pt,
/**********************************************************************/
FNOV_RANK *rank )
{
if( (rank->control & FNC_TEMPLATE) &&
SymIsFunctionTemplateModel( sym ) ) {
rank->rank = OV_RANK_NO_MATCH;
return;
}
FnovArgRank( src, tgt, pt, rank );
if( (rank->control & FNC_EXCLUDE_CONV) &&
(rank->rank > OV_RANK_TRIVIAL) &&
(TypeReference( tgt ) != NULL) ) {
rank->rank = OV_RANK_NO_MATCH;
} else if( (rank->control & FNC_TEMPLATE) &&
(rank->rank > OV_RANK_TRIVIAL) &&
SymIsFunctionTemplateInst( sym ) ) {
rank->rank = OV_RANK_NO_MATCH;
} else if( (rank->control & FNC_DISTINCT_CHECK) &&
(rank->rank == OV_RANK_SAME) ) {
FnovArgRank( tgt, src, NULL, rank );
}
}
static boolean computeUdcRank( FNOV_INFO* info )
/***************************************************************/
// fill in rankvector, ranking of conversion func return value to arg_list
// if u-d conversion is a candidate, return TRUE, else FALSE
{
FNOV_RANK *frv;
TYPE src;
TYPE tgt;
FNOV_LIST *func;
func = info->candfunc;
src = FunctionDeclarationType( func->sym->sym_type )->of;
tgt = info->alist->type_list[0];
frv = func->rankvector;
doComputeArgRank( func->sym, src, tgt, NULL, frv );
if( frv->rank == OV_RANK_NO_MATCH ) {
return( FALSE );
}
return( TRUE );
}
static void moveRingFromTo( FNOV_LIST **from, FNOV_LIST **to )
/************************************************************/
// remove each element in from list, add each into to list
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?