type.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,314 行 · 第 1/5 页
C
2,314 行
CFatal( "unknown type being compared" );
#else
return( FALSE );
#endif
}
return( TRUE );
}
void TypedefReset( SYMBOL sym, TYPE type )
/****************************************/
{
TYPE typedef_type;
/* we are tweaking the type of a typedef that we want permanently changed */
typedef_type = sym->sym_type;
DbgAssert( typedef_type->id == TYP_TYPEDEF );
/* typedef types are not dupCompare()'d */
typedef_type->of = type;
}
void CheckUniqueType( TYPE newtype )
/**********************************/
{
#ifdef XTRA_RPT
ExtraRptTabIncr( ctr_type_ids, newtype->id, 0 );
ExtraRptTabIncr( ctr_type_ids, TYP_MAX-1, 0 );
if( newtype->id == TYP_FUNCTION ) {
unsigned num_args = newtype->u.f.args->num_args;
if( num_args > ARGS_MAX ) {
num_args = ARGS_MAX;
}
ExtraRptTabIncr( ctr_fn_args, num_args, 0 );
ExtraRptTabIncr( ctr_fn_args, ARGS_MAX+1, 0 );
}
#endif
RingPush( &uniqueTypes, newtype );
}
static TYPE typeDuplicated( // GET DUPLICATED TYPE
TYPE newtype, // - new type
TYPE* head ) // - list head
{
TYPE check;
TYPE newtype_of;
TYPE prev;
type_flag newtype_flag;
prev = NULL;
newtype_of = newtype->of;
newtype_flag = newtype->flag;
ExtraRptZeroCtr( ctr_lookup );
RingIterBeg( *head, check ) {
ExtraRptIncrementCtr( ctr_lookup );
if( check->of == newtype_of ) {
if( check->flag == newtype_flag ) {
if( dupCompare( check, newtype ) ) {
ExtraRptAddtoCtr( ctr_dup_succ_probes, ctr_lookup );
ExtraRptIncrementCtr( ctr_dup_succ );
typeFree( newtype );
newtype = RingPromote( head, check, prev );
return newtype;
}
}
}
prev = check;
} RingIterEnd( check )
#ifdef XTRA_RPT
if( CompFlags.codegen_active ) {
ExtraRptIncrementCtr( ctr_cg_dups_fail );
}
ExtraRptTabIncr( ctr_type_ids, newtype->id, 0 );
ExtraRptTabIncr( ctr_type_ids, TYP_MAX-1, 0 );
if( newtype->id == TYP_FUNCTION ) {
unsigned num_args = newtype->u.f.args->num_args;
if( num_args > ARGS_MAX ) {
num_args = ARGS_MAX;
}
ExtraRptTabIncr( ctr_fn_args, num_args, 0 );
ExtraRptTabIncr( ctr_fn_args, ARGS_MAX+1, 0 );
}
#endif
ExtraRptAddtoCtr( ctr_dup_fail_probes, ctr_lookup );
ExtraRptIncrementCtr( ctr_dup_fail );
newtype = RingPush( head, newtype );
return newtype;
}
#define typeHashVal( t ) ((t)->of->dbg.handle & TYPE_HASH_MASK )
static TYPE checkMaybeDupType( TYPE type )
{
if( type->next != NULL ) {
return( type );
}
if( type->next == NULL ) {
TYPE class_type = StructType( type );
if( class_type != NULL && ! TypeDefined( class_type ) ) {
return( type );
}
}
type = CheckDupType( type );
return( type );
}
TYPE CheckDupType( TYPE newtype )
/*******************************/
{
unsigned num_args;
type_id id;
TYPE *head;
DbgAssert( newtype->next == NULL );
id = newtype->id;
ExtraRptIncrementCtr( ctr_dups );
#ifdef XTRA_RPT
if( CompFlags.codegen_active ) {
ExtraRptIncrementCtr( ctr_cg_dups );
}
#endif
#ifndef NDEBUG
if( id == TYP_MODIFIER ) {
if( newtype->flag == TF1_NULL ) {
if( newtype->u.m.base == NULL ) {
if( newtype->u.m.pragma == NULL ) {
CFatal( "empty modifier created" );
}
}
}
}
#endif
head = typeHashTables[ id ];
if( head == NULL ) {
switch( id ) {
case TYP_FUNCTION:
DbgVerify( newtype->of != NULL
, "type: attempt to set base type to NULL" );
num_args = newtype->u.f.args->num_args;
if( num_args < ARGS_HASH ) {
ExtraRptIncrementCtr( ctr_dup_fns );
head = &fnHashTable[ num_args ][ typeHashVal( newtype ) ];
} else if( num_args < ARGS_MAX ) {
ExtraRptIncrementCtr( ctr_dup_fns );
head = &fnTable[ num_args - ARGS_HASH ];
} else {
ExtraRptIncrementCtr( ctr_dup_fns_big );
head = &typeTable[ id ];
}
newtype = typeDuplicated( newtype, head );
break;
case TYP_MEMBER_POINTER:
case TYP_GENERIC:
newtype = typeDuplicated( newtype, &typeTable[ id ] );
break;
default:
#ifdef XTRA_RPT
if( CompFlags.codegen_active ) {
ExtraRptIncrementCtr( ctr_cg_dups_fail );
}
ExtraRptTabIncr( ctr_type_ids, id, 0 );
ExtraRptTabIncr( ctr_type_ids, TYP_MAX-1, 0 );
if( id == TYP_FUNCTION ) {
unsigned num_args = newtype->u.f.args->num_args;
if( num_args > ARGS_MAX ) {
num_args = ARGS_MAX;
}
ExtraRptTabIncr( ctr_fn_args, num_args, 0 );
ExtraRptTabIncr( ctr_fn_args, ARGS_MAX+1, 0 );
}
#endif
newtype = RingPush( &typeTable[ id ], newtype );
}
} else {
if( head == arrayHashTable ) {
if( newtype->u.a.array_size == 0 ) {
/* lets us change the size without worrying about duplicates */
return( newtype );
}
}
DbgVerify( newtype->of != NULL
, "type: attempt to set base type to NULL" );
newtype = typeDuplicated( newtype
, &head[ typeHashVal( newtype ) ] );
}
return newtype;
}
static void traverseTypeRing( // TRAVERSE RING OF TYPES
TYPE ring, // - the ring
void (*rtn)( TYPE, void* ), // - the routine
void* data ) // - data for the routine
{
TYPE curr;
RingIterBeg( ring, curr ) {
(*rtn)( curr, data );
} RingIterEnd( curr )
}
static void traverseTypeHashed( // TRAVERSE VECTOR OF HASHED TYPE RINGS
TYPE* vector, // - the vector
void (*rtn)( TYPE, void* ), // - the routine
void* data ) // - data for the routine
{
int idx; // - index
for( idx = 0; idx < TYPE_HASH_MODULUS; ++ idx ) {
traverseTypeRing( *vector, rtn, data );
++ vector;
}
}
void TypeTraverse( type_id id, void (*rtn)( TYPE, void *), void *data )
/*********************************************************************/
{
unsigned num_args;
switch( id ) {
case TYP_POINTER :
traverseTypeHashed( pointerHashTable, rtn, data );
break;
case TYP_BITFIELD :
traverseTypeHashed( bitfieldHashTable, rtn, data );
break;
case TYP_ARRAY :
traverseTypeHashed( arrayHashTable, rtn, data );
break;
case TYP_MODIFIER :
traverseTypeHashed( modifierHashTable, rtn, data );
break;
case TYP_FUNCTION :
traverseTypeRing( typeTable[id], rtn, data );
for( num_args = 0; num_args < ARGS_HASH; ++num_args ) {
traverseTypeHashed( fnHashTable[ num_args ], rtn, data );
}
for( ; num_args < ARGS_MAX; ++num_args ) {
traverseTypeRing( fnTable[ num_args - ARGS_HASH ], rtn, data );
}
break;
default :
traverseTypeRing( typeTable[id], rtn, data );
break;
}
}
TYPE TypeUserConversion( DECL_SPEC *dspec, DECL_INFO *dinfo )
/***********************************************************/
{
TYPE cnv_id_type;
if( dinfo == NULL ) {
dinfo = makeDeclInfo( NULL );
}
dinfo = FinishDeclarator( dspec, dinfo );
cnv_id_type = dinfo->type;
FreeDeclInfo( dinfo );
return( cnv_id_type );
}
static DECL_INFO *prependTypeToDeclarator( DECL_INFO *dinfo, TYPE type )
{
TYPE end;
if( type != NULL ) {
end = type;
for(;;) {
if( end->of == NULL ) break;
end = end->of;
}
end->of = dinfo->list;
dinfo->list = type;
}
return( dinfo );
}
DECL_INFO *MakeNewDeclarator( DECL_SPEC *dspec,DECL_INFO *ptrs,DECL_INFO*arrays)
/******************************************************************************/
{
if( arrays == NULL ) {
arrays = makeDeclInfo( NULL );
}
if( ptrs != NULL ) {
arrays = prependTypeToDeclarator( arrays, ptrs->list );
/* we've detached the list of types */
ptrs->list = NULL;
FreeDeclInfo( ptrs );
}
arrays = FinishDeclarator( dspec, arrays );
#ifndef NDEBUG
if( PragDbgToggle.dump_types ) {
DumpFullType( arrays->type );
}
#endif
return( arrays );
}
DECL_INFO *MakeNewPointer( specifier_t cv_spec, DECL_INFO *dinfo, PTREE member )
/******************************************************************************/
{
TYPE ptr_type;
TYPE class_type;
if( dinfo == NULL ) {
dinfo = makeDeclInfo( NULL );
}
if( member != NULL ) {
class_type = extractMemberType( member );
ptr_type = makeMemberPointerType( class_type, cv_spec );
} else {
ptr_type = MakePointerType( TF1_NULL, cv_spec );
}
return( prependTypeToDeclarator( dinfo, ptr_type ) );
}
DECL_INFO *MakeNewDynamicArray( PTREE nelem )
/*******************************************/
{
DECL_INFO *dinfo;
dinfo = makeDeclInfo( NULL );
dinfo->defarg_expr = nelem;
return( dinfo );
}
DECL_INFO *AddArrayDeclarator( DECL_INFO *dinfo, PTREE size )
/***********************************************************/
{
TYPE array_type;
if( size != NULL ) {
CheckDimension( size );
array_type = MakeArrayType( size->u.uint_constant );
PTreeFree( size );
} else {
array_type = MakeArrayType( 0 );
}
return( prependTypeToDeclarator( dinfo, array_type ) );
}
static void freeDeclList( DECL_INFO **arg_decls )
{
DECL_INFO *curr;
RingIterBegSafe( *arg_decls, curr ) {
FreeDeclInfo( curr );
} RingIterEndSafe( curr )
*arg_decls = NULL;
}
static void stripDefArg( DECL_INFO *dinfo )
{
PTREE expr;
REWRITE *rewrite;
if( dinfo->has_defarg ) {
expr = dinfo->defarg_expr;
if( expr != NULL ) {
PTreeFreeSubtrees( expr );
dinfo->defarg_expr = NULL;
}
rewrite = dinfo->defarg_rewrite;
if( rewrite != NULL ) {
RewriteFree( rewrite );
dinfo->defarg_rewrite = NULL;
}
dinfo->has_defarg = FALSE;
}
}
static void removeDefaultArgs( DECL_INFO *dinfo )
{
DECL_INFO *curr;
RingIterBeg( dinfo, curr ) {
stripDefArg( curr );
} RingIterEnd( curr )
}
static boolean cantHaveDefaultArgs( int err_msg, DECL_INFO *dinfo )
{
DECL_INFO *curr;
RingIterBeg( dinfo, curr ) {
if( curr->has_defarg ) {
CErr1( err_msg );
return( TRUE );
}
} RingIterEnd( curr )
return( FALSE );
}
/*
// cantHaveDefaultArgGaps
// Supposedly checks for gaps in default arguments. Don't think it works!
// called from:
// ForceNoDefaultArgs (called from FinishDeclarator)
// FreeArgs (only called from template.c (not any more!))
// checkUsefulParms (called from FinishDeclarator)
*/
static boolean cantHaveDefaultArgGaps( DECL_INFO *dinfo )
{
boolean transition_detected;
DECL_INFO *prev_init;
DECL_INFO *curr;
transition_detected = FALSE;
prev_init = NULL;
RingIterBeg( dinfo, curr ) {
if( curr->has_defarg ) {
if( prev_init == NULL ) {
if( transition_detected ) {
CErr1( ERR_DEFAULT_ARGS_MISSING );
return( TRUE );
}
transition_detected = TRUE;
}
prev_init = curr;
} else {
prev_init = NULL;
}
} RingIterEnd( curr )
return( FALSE );
}
/*
* see 14.1 p11:
* If a template-parameter has a default template-argument, all
* subsequent template-parameters shall have a default
* template-argument supplied.
*
* only called from: FreeArgsDefaultsOK (only called from template.c)
*/
static boolean checkForMissingDefaultArgs( DECL_INFO *dinfo )
{
boolean prev_defarg;
DECL_INFO *curr;
prev_defarg = FALSE;
RingIterBeg( dinfo, curr ) {
if( curr->has_defarg ) {
prev_defarg = ( curr != NULL );
} else if( prev_defarg ) {
/* previous parameter had a default argument, but this one
* hasn't => error */
if( curr->generic_sym ) {
SetErrLoc( &curr->generic_sym->locn->tl);
} else {
SetErrLoc( &curr->sym->locn->tl);
}
CErr1( ERR_DEFAULT_ARGS_MISSING );
return( TRUE );
}
} RingIterEnd( curr )
return( FALSE );
}
void ForceNoDefaultArgs( DECL_INFO *dinfo, int err_msg )
/******************************************************/
{
DECL_INFO *parms;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?