static unsigned GblNameHash( const char *name, size_t name_len ) { unsigned rtrn; rtrn = name_len; rtrn += toupper( GETU8( name ) ); rtrn += toupper( GETU8( name + name_len / 2 ) ); rtrn += toupper( GETU8( name + name_len - 1 ) ); return( rtrn & (SYM_TAB_SIZE - 1) ); }
static void CollectSymHdl( const char *ep, imp_sym_handle *is ) { byte *sp; byte curr; static byte escapes[] = { SH_ESCAPE, '\0', '`' }; ++ep; sp = (byte *)is; ++is; while( sp < (byte *)is ) { curr = GETU8( ep++ ); if( curr == SH_ESCAPE ) curr = escapes[GETU8( ep++ ) - 1]; *sp++ = curr; } }
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 ); }