dftype.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,391 行 · 第 1/3 页
C
1,391 行
/*
Fill in the type information for the type handle. The location
context is being passed in because it might be needed to calculate
the size of the type (variable dimensioned arrays and the like).
*/
InitTypeHandle( ii, it, lc );
MapImpTypeInfo( &it->typeinfo, ti );
if( ti->kind == TK_INTEGER ){ // this can be removed when 10.5 gets updated
char *name;
name = DRGetName( it->type );
if( name != NULL ){
if( strcmp( name, "char" ) == 0
|| strcmp( name, "unsigned char" ) == 0 ){
ti->kind = TK_CHAR;
}
DCFree( name );
}
}
return( DS_OK );
}
dip_status DIPENTRY DIPImpTypeBase( imp_image_handle *ii,
imp_type_handle *it, imp_type_handle *base,
location_context *lc, location_list *ll )
{
dr_handle btype;
/*
Given an implementation type handle, fill in 'base' with the
base type of the handle.
*/
if( base != it ){
*base = *it;
}
DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
if( base->state == DF_SET && base->sub_array ){
base->array.index = GetArrayDim( base->array.index, 1 );
if( base->array.is_based ){
base->array.is_set = FALSE;
}
base->array.is_based = TRUE;
if( base->array.index != NULL ){
return( DS_OK );
}
}
btype = DRSkipTypeChain( base->type ); /* skip modifiers and typedefs */
base->type = DRGetTypeAT( btype ); /* get base type */
if( base->type == NULL ) {
base->type = DR_HANDLE_VOID; /* no type means 'void' */
}
base->state = DF_NOT;
return( DS_OK );
}
typedef struct {
int_32 low;
int_32 high;
}enum_range;
static int AEnum( dr_handle var, int index, void *_de ) {
enum_range *de = _de;
int_32 value;
index = index;
if( !DRConstValAT( var, (uint_32 *)&value ) ){
return( FALSE );
}
if( value < de->low ){
de->low = value;
}else if( value > de->high ){
de->high = value;
}
return( TRUE );
}
static int ArrayEnumType( dr_handle tenu, int index, void *_df ) {
/****************************************************************/
// Find low, high bounds of enum
//TODO:unsigned range
array_wlk_wlk *df = _df;
enum_range de;
int_32 count;
index = index;
de.low = LONG_MIN;
de.high = LONG_MAX;
if( !DRWalkEnum( tenu, AEnum, &de )){
return( FALSE );
}
df->low = de.low;
count = de.high-de.low+1;
df->count *= count;
df->dim++;
return( df->cont );
}
static int GetSymVal( imp_image_handle *ii,
dr_handle dr_sym, location_context *lc,
long *ret ){
// Find value of scalar
dr_handle dr_type;
dr_typeinfo typeinfo[1];
uint_32 seg;
location_list src;
location_list dst;
im_idx imx;
dr_type = DRGetTypeAT( dr_sym );
if( dr_type == NULL ){
return( FALSE );
}
DRGetTypeInfo( dr_type, typeinfo );
if( typeinfo->size > sizeof( *ret ) ){
return( FALSE );
}
imx = DwarfModIdx( ii, dr_sym );
if( imx == INVALID_IMX ){
return( FALSE );
}
if( ii->mod_map[imx].is_segment == FALSE ){
seg = SEG_DATA; // if flat hoke segment
}else{
EvalSeg( ii, dr_sym, &seg );
}
if( EvalLocation( ii, lc, dr_sym, seg, &src ) != DS_OK ){
return( FALSE );
}
LocationCreate( &dst, LT_INTERNAL, ret );
if( DCAssignLocation( &dst, &src, typeinfo->size ) != DS_OK ){
return( FALSE );
}
return( TRUE );
}
static int GetDrVal( array_wlk_wlk *df, dr_val32 *val, int_32 *ret ){
/*******************************************/
// extract the value from val
switch( val->val_class ){
case DR_VAL_INT:
*ret = val->val.s;
return( TRUE );
case DR_VAL_REF:
if( DRConstValAT( val->val.ref, (uint_32*)ret ) ){
return( TRUE );
}else if( GetSymVal( df->ii, val->val.ref, df->lc, ret ) ){
return( TRUE );
}
}
return( FALSE );
}
static int ArraySubRange( dr_handle tsub, int index, void *_df ) {
/****************************************************************/
array_wlk_wlk *df = _df;
dr_subinfo info;
int_32 low;
int_32 high;
int_32 count;
index = index;
DRGetSubrangeInfo( tsub, &info );
/* DWARF 2.0 specifies lower bound defaults for C/C++ (0) and FORTRAN (1) */
if( info.low.val_class == DR_VAL_NOT ) {
if( df->ii->mod_map[df->it->imx].lang == DR_LANG_FORTRAN )
low = 1;
else
low = 0;
} else {
GetDrVal( df, &info.low, &low );
}
if( info.count.val_class == DR_VAL_NOT ){
if( info.high.val_class == DR_VAL_NOT ){
return( FALSE );
}
GetDrVal( df, &info.high, &high );
count = high - low +1;
}else{
GetDrVal( df, &info.count, &count );
}
df->low = low;
df->count *= count;
df->dim++;
return( df->cont );
}
dip_status DIPENTRY DIPImpTypeArrayInfo( imp_image_handle *ii,
imp_type_handle *array, location_context *lc,
array_info *ai, imp_type_handle *index )
{
/*
Given an implemenation type handle that represents an array type,
get information about the array shape and index type. The location
context is for variable dimensioned arrays again. The 'index'
parameter is filled in with the type of variable used to subscript
the array. It may be NULL, in which case no information is returned.
*/
DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
if( array->state == DF_NOT ){
InitTypeHandle( ii, array, lc );
}
if( array->state == DF_NOT ){
DCStatus( DS_ERR | DS_BAD_PARM );
return( DS_ERR | DS_BAD_PARM );
}
if( array->typeinfo.kind != DR_TYPEK_ARRAY ){
DCStatus( DS_ERR | DS_BAD_PARM );
return( DS_ERR | DS_BAD_PARM );
}
ai->low_bound = array->array.low;
ai->num_elts = array->array.num_elts;
ai->num_dims = array->array.dims;
ai->column_major = array->array.column_major;
ai->stride = array->array.base_stride;
if( index != NULL ){
index->imx = array->imx;
if( array->array.index == NULL ){ //Fake a type up
index->state = DF_SET;
index->type = NULL;
index->typeinfo.size = 0;
index->typeinfo.kind = DR_TYPEK_NONE;
index->typeinfo.mclass = DR_MOD_NONE;
}else{
index->state = DF_NOT;
index->type = array->array.index;
}
}
return( DS_OK );
}
/*
Given an implementation type handle that represents a procedure type,
get information about the return and parameter types. If the 'n'
parameter is zero, store the return type handle into the 'parm'
variable. Otherwise store the handle for the n'th parameter in
'parm'.
*/
typedef struct {
int count;
int last;
dr_handle var;
}parm_wlk;
static int AParm( dr_handle var, int index, void *_df ) {
/*******************************************************/
parm_wlk *df = _df;
index = index;
++df->count;
if( df->count == df->last ){
df->var = var;
return( FALSE );
}else{
return( TRUE );
}
}
extern dr_handle GetParmN( imp_image_handle *ii,dr_handle proc, int count ){
/******************************************************/
// return handle of the n parm
parm_wlk df;
dr_handle ret;
df.count = 0;
df.last = count;
DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
if( DRWalkBlock( proc, DR_SRCH_parm, AParm, &df ) ){
ret = NULL;
}else{
ret = df.var;
}
return( ret );
}
extern int GetParmCount( imp_image_handle *ii, dr_handle proc ){
/******************************************************/
// return handle of the n parm
parm_wlk df;
df.count = 0;
df.last = 0;
DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
DRWalkBlock( proc, DR_SRCH_parm, AParm, &df );
return( df.count );
}
dip_status DIPENTRY DIPImpTypeProcInfo( imp_image_handle *ii,
imp_type_handle *proc, imp_type_handle *parm, unsigned n )
{
dr_handle btype;
dr_handle parm_type;
dip_status ret;
DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
btype = DRSkipTypeChain( proc->type ); /* skip modifiers and typedefs */
if( n > 0 ){
btype = GetParmN( ii, btype, n );
}// if n == 0 just fall through and get type of function
if( btype != NULL ){
parm_type = DRGetTypeAT( btype ); /* get type */
}
if( parm_type != NULL ){
parm->state = DF_NOT;
parm->type = parm_type;
parm->imx = proc->imx;
ret = DS_OK;
}else{
ret = DS_FAIL;
}
return( ret );
}
dip_status DIPENTRY DIPImpTypePtrAddrSpace( imp_image_handle *ii,
imp_type_handle *it, location_context *lc, address *a )
{
/*
Given an implementation type handle that represents a pointer type,
get information about any implied address space for that pointer
(based pointer cruft). If there is an implied address space for
the pointer, fill in *a with the information and return DS_OK.
Otherwise return DS_FAIL.
*/
dip_status ret;
ret = EvalBasedPtr( ii, lc, it->type, a );
return( ret );
}
int DIPENTRY DIPImpTypeCmp( imp_image_handle *ii, imp_type_handle *it1,
imp_type_handle *it2 )
{
long diff;
ii = ii;
diff = it1->type - it2->type;
return( diff );
}
/*****************************/
/* Structure Enum Walks */
/*****************************/
typedef struct inh_vbase {
struct inh_vbase *next;
dr_handle base;
}inh_vbase;
typedef struct{
im_idx imx;
imp_image_handle *ii;
sym_sclass sclass;
void *d;
dr_handle root;
dr_handle inh;
inh_vbase *vbase;
enum_einfo einfo;
}type_wlk_com;
typedef struct {
type_wlk_com com;
IMP_SYM_WKR *wk;
imp_sym_handle *is;
walk_result wr;
}type_wlk_wlk;
typedef struct {
type_wlk_com com;
int (*comp)();
lookup_item *li;
search_result sr;
}type_wlk_lookup;
typedef union {
type_wlk_com com;
type_wlk_wlk sym;
type_wlk_lookup lookup;
}type_wlk;
static int AddBase( dr_handle base, inh_vbase **lnk ){
/*****************************************************/
//if base not in list add return FALSE
inh_vbase *cur;
while( (cur = *lnk) != NULL ){
if( base <= cur->base ){
if( base == cur->base ){
return( FALSE);
}
break;
}
lnk = &cur->next;
}
cur = DCAlloc( sizeof( *cur ) );
cur->base = base;
cur->next = *lnk;
*lnk = cur;
return( TRUE );
}
static int FreeBases( void *_lnk ){
/***************************************/
//Free bases
inh_vbase **lnk = _lnk;
inh_vbase *cur;
inh_vbase *old;
cur = *lnk;
while( cur != NULL ){
old = cur;
cur = cur->next;
DCFree( old );
}
*lnk = NULL;
return 0;
}
static int AMem( dr_handle var, int index, void *d );
static int AInherit( dr_handle inh, int index, void *d );
static DRWLKBLK StrucWlk[DR_WLKBLK_STRUCT] = {
AMem,
AInherit,
AMem,
AMem,
NULL
};
static void SetSymHandle( type_wlk *d, imp_sym_handle *is ){
// Set is with info from com
is->sclass = d->com.sclass;
is->imx = d->com.imx;
is->state = DF_NOT;
if( d->com.sclass == SYM_ENUM ){
is->f.einfo = d->com.einfo;
}else{
is->f.minfo.root = d->com.root;
is->f.minfo.inh = d->com.inh;
}
}
static int AMem( dr_handle var, int index, void *_d ) {
/*****************************************************/
type_wlk_wlk *d = _d;
int cont;
imp_sym_handle *is;
dr_dbg_handle saved;
cont = TRUE;
is = d->is;
SetSymHandle( (type_wlk *)d, is );
is->sym = var;
switch( index ){
case 0:
is->sclass = SYM_MEM;
break;
case 2:
is->sclass = SYM_MEMVAR; // static member
break;
case 3:
if( DRGetVirtuality( var ) == DR_VIRTUALITY_VIRTUAL ){
is->sclass = SYM_VIRTF; // virtual func
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?