TYPE TypeMergeForMember( // CREATE MERGED TYPE FOR A MEMBER TYPE owner, // - type on left (.), type pointed at (->) TYPE member ) // - type for member { type_flag owner_flags; // - modifier flags for owner type_flag member_flags; // - modifier flags for member type_flag result_flags; // - modifier flags for result void *owner_base; // - base for owner TypeModExtract( owner , &owner_flags , &owner_base , TC1_NOT_ENUM_CHAR ); member = TypeGetActualFlags( member, &member_flags ); if( owner_flags & TF1_CONST ) { if( member_flags & TF1_MUTABLE ) { owner_flags &= ~TF1_CONST; } } result_flags = owner_flags | member_flags; if( result_flags != TF1_NULL ) { member = MakeBasedModifierOf( member, result_flags, owner_base ); } return( member ); }
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 TypeCompareExclude( TYPE type1, TYPE type2, type_exclude mask ) /******************************************************************/ { TC_STATE state; type_flag flag1; type_flag flag2; void *base1; void *base2; TC_DATA *stack; if( type1 == type2 ) { return( true ); } stack = NULL; state = FOLLOW_OF; for(;;) { if( type1 == NULL || type2 == NULL ) break; // tweak type1 and type2 to ignore minor distinctions type1 = TypeModExtract( type1, &flag1, &base1, mask|TC1_NOT_MEM_MODEL ); type2 = TypeModExtract( type2, &flag2, &base2, mask|TC1_NOT_MEM_MODEL ); if( type1 == NULL || type2 == NULL ) break; if( mask & TC1_PTR_FUN ) { type_flag extra; // tweak type1 and type2 to ignore more major distinction if( ( type1->id == TYP_POINTER ) &&( type2->id == TYP_FUNCTION ) ) { type2 = TypeModFlagsEC( MakePointerTo( type2 ), &extra ); flag2 |= extra; } else if( ( type2->id == TYP_POINTER ) &&( type1->id == TYP_FUNCTION ) ) { type1 = TypeModFlagsEC( MakePointerTo( type1 ), &extra ); flag1 |= extra; } } if( ( type1->id == TYP_CLASS ) && ( type1->flag & TF1_UNBOUND ) && ( type1->of != NULL ) ) { type1 = type1->of; } if( ( type2->id == TYP_CLASS ) && ( type2->flag & TF1_UNBOUND ) && ( type2->of != NULL ) ) { type2 = type2->of; } // compare type1 and type2 flag1 &= ~TF1_MOD_IGNORE; flag2 &= ~TF1_MOD_IGNORE; if( flag1 != flag2 ) { break; } else if( (flag1 & TF1_BASED) && !TypeBasesEqual( flag1, base1, base2 ) ) { break; } else if( type1 == type2 ) { state = FOLLOW_STACK; } else { if( !typeCompareCurrent( &stack, type1, type2, mask ) ) { break; } } // advance the type pointers for( ; ; ) { TC_DATA *top; unsigned arg_index; switch( state ) { case FOLLOW_OF: type1 = type1->of; type2 = type2->of; break; case FOLLOW_STACK: top = stack; if( top == NULL ) { return( true ); } state = FOLLOW_OF; switch( top->flavour ) { case FUNCTION: arg_index = --top->arg_index; type1 = top->type1->u.f.args->type_list[arg_index]; type2 = top->type2->u.f.args->type_list[arg_index]; mask = top->mask; if( arg_index == 0 ) { popTC_DATA( &stack ); } break; case MEMBER_POINTER: type1 = top->type1->u.mp.host; type2 = top->type2->u.mp.host; mask = top->mask; popTC_DATA( &stack ); break; } break; } if( type1 == type2 ) { state = FOLLOW_STACK; continue; } break; } } while( stack != NULL ) { popTC_DATA( &stack ); } return( false ); }