Beispiel #1
0
static void DumpBaseType( TYPEPTR typ, STRCHUNK *pch )
{
    SYM_ENTRY           sym;
    TYPEPTR             obj;

    for( ; typ->decl_type != TYPE_TYPEDEF && typ->decl_type != TYPE_ENUM; ) {
        obj = Object( typ );
        if( obj == NULL )
            break;
        typ = obj;
    }
    SKIP_DUMMY_TYPEDEFS( typ );
    if( typ->decl_type == TYPE_TYPEDEF ) {
        SymGet( &sym, typ->u.typedefn );
        ChunkSaveStrWord( pch, SymName( &sym, typ->u.typedefn ) );
    } else {
        if( typ->type_flags & TF2_TYPE_PLAIN_CHAR ) {
            ChunkSaveStrWord( pch, "char" );
        } else {
            ChunkSaveStrWord( pch, CTypeNames[typ->decl_type] );
        }
        if( typ->decl_type == TYPE_STRUCT || typ->decl_type == TYPE_UNION
          || typ->decl_type == TYPE_ENUM ) {

            /* if there is no tag name, then should print out the
               entire structure or union definition or enum list */

            DumpTagName( typ->u.tag->name, pch );
        }
    }
}
Beispiel #2
0
static aux_info *InfoLookup( SYMPTR sym )
{
    char            *name;
    aux_info        *inf;
    aux_entry       *ent;

    name = sym->name;
    inf = &DefaultInfo;         /* assume default */
    if( name == NULL )
        return( inf );
    ent = AuxLookup( name );
    if( ent != NULL )
        inf = ent->info;
    if( ( ent == NULL ) || (sym->flags & SYM_INTRINSIC) ) {
        if( sym->flags & SYM_DEFINED )
            return( inf );
        if( (sym->flags & SYM_INTRINSIC) == 0 ) {
            if( memcmp( name, "_inline_", 8 ) != 0 )
                return( inf );
            name += 8;
        }
#if ( _CPU == 8086 ) || ( _CPU == 386 )
        {
            const inline_funcs  *ifunc;

            ifunc = IF_Lookup( name );
            if( ifunc == NULL )
                return( inf );
  #if ( _CPU == 8086 )
            if( HW_CEqual( ifunc->returns, HW_DX_AX )
              || HW_CEqual( ifunc->returns, HW_DS_SI )
              || HW_CEqual( ifunc->returns, HW_ES_DI )
              || HW_CEqual( ifunc->returns, HW_CX_DI ) ) {
                if( SizeOfArg( sym->sym_type->object ) != 4 ) {
  #else
            if( HW_CEqual( ifunc->returns, HW_DX_AX )
              || HW_CEqual( ifunc->returns, HW_DS_ESI )
              || HW_CEqual( ifunc->returns, HW_ES_EDI )
              || HW_CEqual( ifunc->returns, HW_CX_DI ) ) {
                if( SizeOfArg( sym->sym_type->object ) != 6 ) {
  #endif
                    return( inf );
                }
            }
            inf = &InlineInfo;
            inf->cclass = (WatcallInfo.cclass & FAR_CALL) | MODIFY_EXACT;
            if( (sym->flags & SYM_INTRINSIC) && ( ent != NULL ) )
                inf->cclass |= ent->info->cclass;
            inf->code = ifunc->code;
            inf->parms = ifunc->parms;
            inf->returns = ifunc->returns;
  #if ( _CPU == 8086 )
            if( !HW_CEqual( inf->returns, HW_AX )
              && !HW_CEqual( inf->returns, HW_EMPTY ) ) {
  #else
            if( !HW_CEqual( inf->returns, HW_EAX )
              && !HW_CEqual( inf->returns, HW_EMPTY ) ) {
  #endif
                inf->cclass |= SPECIAL_RETURN;
            }
            HW_CAsgn( inf->streturn, HW_EMPTY );
            inf->save = ifunc->save;
            inf->objname = WatcallInfo.objname;
            inf->use = 1;
        }
#endif
    }
    return( inf );
}

aux_info *FindInfo( SYMPTR sym, SYM_HANDLE sym_handle )
{
    SYM_ENTRY       sym_typedef;
    aux_entry       *ent;
    TYPEPTR         typ;
    aux_info        *inf;

    inf = &DefaultInfo;         /* assume default */
    if( sym_handle == SYM_NULL )
        return( inf );

    SymGet( sym, sym_handle );
#if _CPU == 386
    if( (sym_handle == SymSTOSB) || (sym_handle == SymSTOSD) ) {
        return( &STOSBInfo );
    } else if( sym_handle == SymFinally ) {
        InlineInfo = WatcallInfo;
        InlineInfo.code = (byte_seq *)&FinallyCode;
        return( &InlineInfo );
    } else if( sym_handle == SymTryFini ) {
        InlineInfo = WatcallInfo;
        InlineInfo.parms = TryFiniParms;
        InlineInfo.code = (byte_seq *)&TryFiniCode;
        return( &InlineInfo );
    }
#endif
    if( (sym->flags & SYM_TEMP) == 0 ) {
        /* not an indirect func call*/
        inf = InfoLookup( sym );
    }
    if( inf == &DefaultInfo ) {
        typ = sym->sym_type;
        SKIP_DUMMY_TYPEDEFS( typ );
        if( typ->decl_type == TYPE_TYPEDEF ) {
            SymGet( &sym_typedef, typ->u.typedefn );
            if( sym_typedef.name != NULL ) {
                ent = AuxLookup( sym_typedef.name );
                if( ent != NULL ) {
                    inf = ent->info;
                }
            }
        }
    }
#if _CPU == 386
    if( (inf->flags & AUX_FLAG_FAR16) || (sym->mods & FLAG_FAR16) ) {
        if( (sym->mods & MASK_LANGUAGES) == LANG_PASCAL || (inf->cclass & REVERSE_PARMS) ) {
            return( &Far16PascalInfo );
        } else {
            return( &Far16CdeclInfo );
        }
    }
#endif
    return( inf );
}

bool FunctionAborts( SYMPTR sym, SYM_HANDLE sym_handle )
{
    aux_entry    *ent;

    if( sym_handle != SYM_NULL ) {
        SymGet( sym, sym_handle );
        ent = AuxLookup( SymName( sym, sym_handle ) );
        if( ent != NULL ) {
            if( ent->info->cclass & SUICIDAL ) {
                return( TRUE );
            }
        }
    }
    return( FALSE );
}

call_class GetCallClass( SYM_HANDLE sym_handle )
{
    aux_info            *inf;
    SYM_ENTRY           sym;
    call_class          cclass;

    cclass = DefaultInfo.cclass;
    if( sym_handle != SYM_NULL ) {
        inf = FindInfo( &sym, sym_handle );
        if( sym.flags & SYM_FUNCTION ) {
            if( inf != &DefaultInfo ) {
                cclass = inf->cclass;
            } else {
                cclass = GetLangInfo( sym.mods )->cclass;
#if _CPU == 8086
                if( TargSys == TS_WINDOWS ) {
                    if( sym.mods & (LANG_CDECL | LANG_PASCAL) ) {
                        cclass |= FAT_WINDOWS_PROLOG;
                    }
                }
#endif
            }
#if ( _CPU == 8086 ) || ( _CPU == 386 )
            if( CompFlags.emit_names ) {
                cclass |= EMIT_FUNCTION_NAME;
            }
            if( sym.mods & FLAG_FAR ) {
                cclass |= FAR_CALL;
                if( sym.mods & FLAG_NEAR ) {
                    cclass |= INTERRUPT;
                }
            } else if( sym.mods & FLAG_NEAR ) {
                cclass &= ~ FAR_CALL;
            }
#endif
#ifdef DLL_EXPORT
            if( sym.mods & FLAG_EXPORT ) {
                cclass |= DLL_EXPORT;
            }
#endif
#ifdef LOAD_DS_ON_ENTRY
            if( sym.mods & FLAG_LOADDS ) {
  #if 0
                if( TargSys == TS_WINDOWS ) {
                    cclass |= FAT_WINDOWS_PROLOG;
                } else {
                    cclass |= LOAD_DS_ON_ENTRY;
                }
  #else
                cclass |= LOAD_DS_ON_ENTRY;
  #endif
            }
#endif
#ifdef MAKE_CALL_INLINE
            if( IsInLineFunc( sym_handle ) ) {
                cclass |= MAKE_CALL_INLINE;
            }
#endif
            if( VarFunc( &sym ) ) {
                cclass |= CALLER_POPS | HAS_VARARGS;
            }
        }
#if ( _CPU == 8086 ) || ( _CPU == 386 )
        if( sym.flags & SYM_FUNC_NEEDS_THUNK ) {
            cclass |= THUNK_PROLOG;
        }
#endif
    }
#ifdef REVERSE
    cclass &= ~ REVERSE_PARMS;
#endif
#ifdef PROLOG_HOOKS
    if( CompFlags.ep_switch_used != 0 ) {
        cclass |= PROLOG_HOOKS;
    }
#endif
#ifdef EPILOG_HOOKS
    if( CompFlags.ee_switch_used != 0 ) {
        cclass |= EPILOG_HOOKS;
    }
#endif
#ifdef GROW_STACK
    if( CompFlags.sg_switch_used ) {
        cclass |= GROW_STACK;
    }
#endif
#ifdef TOUCH_STACK
    if( CompFlags.st_switch_used ) {
        cclass |= TOUCH_STACK;
    }
#endif
    return( cclass );
}