static search_result DoLookupSym( imp_image_handle *ii, symbol_source ss, void *source, lookup_item *li, location_context *lc, void *d ) { imp_mod_handle im; search_result sr; lookup_item sym_li; char *buff; const char *src; char *dst; size_t len; unsigned op_len; imp_sym_handle *scope_is; lc = lc; if( GETU8( li->name.start ) == SH_ESCAPE ) { CollectSymHdl( li->name.start, DCSymCreate( ii, d ) ); return( SR_EXACT ); } if( li->type == ST_NAMESPACE ) return( SR_NONE ); sym_li = *li; if( ss == SS_SCOPESYM ) { char *scope_name; scope_is = source; len = ImpInterface.SymName( ii, scope_is, NULL, SN_SOURCE, NULL, 0 ); scope_name = __alloca( len + 1 ); ImpInterface.SymName( ii, scope_is, NULL, SN_SOURCE, scope_name, len + 1 ); sym_li.scope.start = scope_name; sym_li.scope.len = len; ss = SS_MODULE; sym_li.mod = IMH2MH( scope_is->im ); source = &sym_li.mod; } if( sym_li.type == ST_OPERATOR ) { src = sym_li.name.start; len = sym_li.name.len; buff = __alloca( len + 20 ); dst = buff; for( ;; ) { if( len == 0 ) break; if( src == sym_li.source.start ) { op_len = __mangle_operator( src, sym_li.source.len, buff ); if( op_len == 0 ) { DCStatus( DS_ERR|DS_INVALID_OPERATOR ); return( SR_NONE ); } dst += op_len; src += sym_li.source.len; len -= sym_li.source.len; } else { *dst++ = *src++; --len; } } sym_li.name.len = dst - buff; sym_li.name.start = buff; } sr = SR_NONE; im = IMH_NOMOD; switch( ss ) { case SS_SCOPED: if( ImpInterface.AddrMod( ii, *(address *)source, &im ) == SR_NONE ) { im = MH2IMH( sym_li.mod ); } else if( MH2IMH( sym_li.mod ) == IMH_NOMOD || MH2IMH( sym_li.mod ) == im ) { if( !sym_li.file_scope && sym_li.type == ST_NONE ) { sr = SearchLclScope( ii, im, (address *)source, &sym_li, d ); } } else { im = MH2IMH( sym_li.mod ); } if( im != IMH_NOMOD && sr == SR_NONE ) { sr = SearchFileScope( ii, im, &sym_li, d ); } break; case SS_MODULE: im = *(imp_mod_handle *)source; if( MH2IMH( sym_li.mod ) == IMH_NOMOD || MH2IMH( sym_li.mod ) == im ) { sr = SearchFileScope( ii, im, &sym_li, d ); } break; case SS_TYPE: if( MH2IMH( sym_li.mod ) != IMH_NOMOD ) return( SR_NONE ); switch( sym_li.type ) { case ST_TYPE: case ST_STRUCT_TAG: case ST_CLASS_TAG: case ST_UNION_TAG: case ST_ENUM_TAG: return( SR_NONE ); } return( SearchMbr( ii, (imp_type_handle *)source, &sym_li, d ) ); } if( sr == SR_NONE ) { switch( sym_li.type ) { case ST_NONE: case ST_DESTRUCTOR: case ST_OPERATOR: sr = SearchGbl( ii, im, MH2IMH( sym_li.mod ), &sym_li, d ); break; } } return( sr ); }
search_result DoLookupSym( imp_image_handle *ii, symbol_source ss, void *source, lookup_item *li, location_context *lc, void *d ) { imp_mod_handle im; search_result sr; lookup_item item; char *buff; char *src; char *dst; unsigned len; unsigned op_len; imp_sym_handle *scope_is; if( *li->name.start == SH_ESCAPE ) { CollectSymHdl( (byte *)li->name.start, DCSymCreate( ii, d ) ); return( SR_EXACT ); } if( li->type == ST_NAMESPACE ) return( SR_NONE ); item = *li; if( ss == SS_SCOPESYM ) { scope_is = source; len = ImpInterface.sym_name( ii, scope_is, NULL, SN_SOURCE, NULL, 0 ); item.scope.start = __alloca( len + 1 ); ImpInterface.sym_name( ii, scope_is, NULL, SN_SOURCE, item.scope.start, len + 1 ); item.scope.len = len; ss = SS_MODULE; item.mod = scope_is->im; source = &item.mod; } if( item.type == ST_OPERATOR ) { src = item.name.start; len = item.name.len; buff = __alloca( len + 20 ); dst = buff; for( ;; ) { if( len == 0 ) break; if( src == item.source.start ) { op_len = __mangle_operator( src, item.source.len, buff ); if( op_len == 0 ) { DCStatus( DS_ERR|DS_INVALID_OPERATOR ); return( SR_NONE ); } dst += op_len; src += item.source.len; len -= item.source.len; } else { *dst++ = *src++; --len; } } item.name.len = dst - buff; item.name.start = buff; } sr = SR_NONE; switch( ss ) { case SS_SCOPED: if( ImpInterface.addr_mod( ii, *(address *)source, &im ) == SR_NONE ) { im = item.mod; } else if( item.mod == NO_MOD || item.mod == im ) { if( !item.file_scope && item.type == ST_NONE ) { sr = SearchLclScope( ii, im, (address *)source, &item, d ); } } else { im = item.mod; } if( im != NO_MOD && sr == SR_NONE ) { sr = SearchFileScope( ii, im, &item, d ); } break; case SS_MODULE: im = *(imp_mod_handle *)source; if( item.mod == NO_MOD || item.mod == im ) { sr = SearchFileScope( ii, im, &item, d ); } break; case SS_TYPE: if( item.mod != NO_MOD ) return( SR_NONE ); switch( item.type ) { case ST_TYPE: case ST_STRUCT_TAG: case ST_CLASS_TAG: case ST_UNION_TAG: case ST_ENUM_TAG: return( SR_NONE ); } return( SearchMbr( ii, (imp_type_handle *)source, &item, d ) ); } if( sr == SR_NONE ) { switch( item.type ) { case ST_NONE: case ST_DESTRUCTOR: case ST_OPERATOR: sr = SearchGbl( ii, im, (imp_mod_handle)item.mod, &item, d ); break; } } return( sr ); }