type.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,314 行 · 第 1/5 页
C
2,314 行
/**********************************/
{
return( MakeTypeOf( MakeVolatileModifier(), type ) );
}
static TYPE makeCompilerData( TYPE type, type_flag flags )
{
if( defaultDataMemFlag & ( TF1_FAR | TF1_HUGE ) ) {
#if _CPU == 8086
if(( flags & TF1_CONST ) == 0 ) {
if( TargetSwitches & WINDOWS ) {
/* R/W data must be near for 16-bit Windows */
flags |= TF1_NEAR;
} else {
flags |= TF1_FAR;
}
} else {
flags |= TF1_FAR;
}
#else
flags |= TF1_FAR;
#endif
}
return( MakeModifiedType( type, flags ) );
}
TYPE MakeCompilerReadWriteData( TYPE type )
/*****************************************/
{
return( makeCompilerData( type, TF1_NULL ) );
}
TYPE MakeCompilerConstData( TYPE type )
/*************************************/
{
return( makeCompilerData( type, TF1_CONST ) );
}
TYPE MakeCompilerConstCommonData( TYPE type )
/*******************************************/
{
return( makeCompilerData( type, TF1_COMMON | TF1_CONST ) );
}
static TYPE makeCompilerReadWriteCommonData( TYPE type )
/******************************************************/
{
return( makeCompilerData( type, TF1_COMMON ) );
}
static void verifyBasedRef( SEARCH_RESULT *result, SYMBOL sym )
{
SCOPE found;
found = result->scope;
if( ScopeType( found, SCOPE_FILE ) ) {
return;
}
if( ScopeType( found, SCOPE_BLOCK ) ) {
return;
}
if( result->no_this ) {
if( ! SymIsStaticDataMember( sym ) ) {
CErr2p( ERR_CANNOT_ALWAYS_ACCESS, sym );
}
}
}
/*
Based pointer examples:
__segment seg_var;
char __far *fp;
(1) char __based(seg_var) *bp; -- fetch segment from seg_var
char __based((__segment)fp)) *ip; -- use of 'fp''s seg value
char __based(fp) *pp; -- add offset to fp to produce pointer
char __based(void) *vp; -- just an offset (based on nothing)
char __based((__segment)__self) *sp; -- inherits base from expression
(2) __based(__segname("_CODE")) -- pre-defined segment names
__based(__segname("_CONST")) (^ code segment) (data segment)
__based(__segname("_DATA")) (data segment)
__based(__segname("_STACK")) (stack segment)
__based(__segname("_MYSEG")) (user-defined segment)
*/
TYPE MakeBasedModifier( type_flag mod, boolean seg_cast, PTREE base )
/*******************************************************************/
{
int based_msg;
SEARCH_RESULT *result;
SYMBOL sym;
SYMBOL_NAME sym_name;
TYPE type;
char *id;
void *base_expr;
base_expr = NULL;
switch( mod ) {
case TF1_BASED_VOID:
case TF1_BASED_SELF:
break;
case TF1_BASED_STRING:
base_expr = base->u.string;
PTreeFree( base );
break;
default:
mod = TF1_BASED_VOID;
id = base->u.id.name;
PTreeFree( base );
result = ScopeFindNaked( GetCurrScope(), id );
if( result == NULL ) {
CErr2p( ERR_UNDECLARED_SYM, id );
} else {
sym_name = result->sym_name;
sym = sym_name->name_syms;
if( ! SymIsAnError( sym ) ) {
if( seg_cast ) {
CErr2p( ERR_BASED_EXTRACT_NO_SEG, sym );
} else {
type = sym->sym_type;
if( IntegralType( type ) != NULL ) {
mod = TF1_BASED_FETCH;
base_expr = sym;
} else {
type = PointerType( type );
based_msg = ERR_BASED_FETCH_NO_SEG;
if( type != NULL ) {
if( type->id != TYP_POINTER ) {
type = NULL;
} else if( type->flag & TF1_REFERENCE ) {
type = NULL;
} else if( BasedType( type->of ) != NULL ) {
based_msg = ERR_BASED_ON_BASED;
type = NULL;
}
}
if( type == NULL ) {
CErr2p( based_msg, sym );
} else {
mod = TF1_BASED_ADD;
base_expr = sym;
}
}
if( base_expr != NULL ) {
if( result->scope != GetCurrScope() ) {
verifyBasedRef( result, sym );
}
}
}
if( base_expr != NULL ) {
if( ScopeCheckSymbol( result, sym ) ) {
mod = TF1_BASED_VOID;
base_expr = NULL;
}
}
}
ScopeFreeResult( result );
}
}
return( makeFullModifier( mod, base_expr, NULL ) );
}
TYPE MakeBasedModifierOf( // MAKE BASED MODIFIER FOR A TYPE
TYPE type, // - basic type
type_flag flags, // - modifier flags
void *baser ) // - baser
{
if( flags == TF1_NULL ) {
return( type );
}
return MakeTypeOf( makeFullModifier( flags, baser, NULL ), type );
}
static type_flag convertCVSpec( specifier_t spec )
{
type_flag flag;
flag = TF1_NULL;
if( spec & STY_CONST ) {
flag |= TF1_CONST;
}
if( spec & STY_VOLATILE ) {
flag |= TF1_VOLATILE;
}
if( spec & STY_UNALIGNED ) {
flag |= TF1_UNALIGNED;
}
return( flag );
}
static TYPE makeAnyPointer( type_id id, specifier_t cv_flags )
{
TYPE ptype;
type_flag cvflag;
ptype = MakeType( id );
cvflag = convertCVSpec( cv_flags );
if( cvflag != NULL ) {
/* build this backwards, since later processing reverses the list */
ptype->of = MakeFlagModifier( cvflag );
}
return( ptype );
}
TYPE MakePointerType( type_flag ref_flag, specifier_t cv_flags )
/**************************************************************/
{
TYPE ptype;
ptype = makeAnyPointer( TYP_POINTER, cv_flags );
ptype->flag |= ref_flag;
return( ptype );
}
static TYPE makeMemberPointerType( TYPE class_type, specifier_t cv_flags )
/************************************************************************/
{
TYPE ptype;
ptype = makeAnyPointer( TYP_MEMBER_POINTER, cv_flags );
ptype->u.mp.host = TypedefRemove( class_type );
return( ptype );
}
static TYPE extractMemberType( PTREE tree )
{
/* we have:
CO_INDIRECT
|
CO_COLON_COLON
/ \
<id>
*/
TYPE type;
type = tree->u.subtree[0]->u.subtree[1]->type;
PTreeFreeSubtrees( tree );
return( type );
}
TYPE MakeMemberPointer( PTREE class_tree, specifier_t cv_flags )
/**************************************************************/
{
TYPE type;
type = extractMemberType( class_tree );
if( type != NULL ) {
type = makeMemberPointerType( type, cv_flags );
}
return( type );
}
TYPE MakeSeg16Pointer( specifier_t cv_flags )
/*******************************************/
{
TYPE ptr_type;
TYPE mod_type;
ptr_type = makeAnyPointer( TYP_POINTER, cv_flags );
mod_type = MakeFlagModifier( TF1_SET_FAR16 );
mod_type->of = ptr_type;
return( mod_type );
}
TYPE MakeMemberPointerTo( TYPE class_type, TYPE base_type )
/*********************************************************/
{
TYPE mptr_type;
TYPE unmod_type;
type_flag flags;
void *base;
class_type = StructType( class_type );
mptr_type = makeMemberPointerType( class_type, STY_NULL );
base_type = TypeReferenced( base_type );
unmod_type = TypeModExtract( base_type, &flags, &base, TC1_NOT_ENUM_CHAR );
if( flags & TF1_MPTR_REMOVE ) {
flags &= ~TF1_MPTR_REMOVE;
base_type = MakeBasedModifierOf( unmod_type, flags, base );
}
return MakeTypeOf( mptr_type, base_type );
}
static boolean newTypeIllegal( TYPE type )
{
boolean error_occurred;
TYPE test_type;
type_flag flags;
error_occurred = FALSE;
test_type = TypeModFlags( type, &flags );
switch( test_type->id ) {
case TYP_FUNCTION:
CErr1( ERR_NEW_TYPE_FUNCTION );
error_occurred = TRUE;
break;
case TYP_VOID:
CErr1( ERR_NEW_TYPE_VOID );
error_occurred = TRUE;
break;
}
if( flags & TF1_CV_MASK ) {
CErr1( WARN_NEW_TYPE_CONST_VOLATILE );
}
return( error_occurred );
}
void CheckNewModifier( type_flag flags )
/**************************************/
{
if( flags & ~TF1_MEM_MODEL ) {
CErr1( ERR_INVALID_NEW_MODIFIER );
} else {
flags &= TF1_MEM_MODEL;
if( flags != defaultDataMemFlag ) {
CErr1( ERR_INVALID_NEW_MODIFIER );
}
}
}
PTREE MakeNewExpr( PTREE gbl, PTREE placement, DECL_INFO *dinfo, PTREE init )
/***************************************************************************/
{
PTREE nelem_expr;
PTREE new_parms1;
PTREE new_parms2;
PTREE new_expr;
PTREE new_type;
CGOP new_op;
TYPE type;
new_op = CO_NEW;
if( gbl != NULL ) {
PTreeFreeSubtrees( gbl );
new_op = CO_NEW_G;
}
nelem_expr = dinfo->defarg_expr;
if( nelem_expr != NULL ) {
// detach from 'dinfo'
dinfo->defarg_expr = NULL;
}
type = dinfo->type;
FreeDeclInfo( dinfo );
if( newTypeIllegal( type ) ) {
PTreeFreeSubtrees( init );
new_expr = PTreeErrorNode( placement );
} else {
new_type = PTreeType( type );
new_parms2 = PTreeBinary( CO_NEW_PARMS2, nelem_expr, init );
new_parms1 = PTreeBinary( CO_NEW_PARMS1, placement, new_parms2 );
new_expr = PTreeBinary( new_op, new_type, new_parms1 );
}
return( new_expr );
}
DECL_INFO *MakeNewTypeId( PTREE type_id )
/***************************************/
{
TYPE new_type;
DECL_INFO *dinfo;
new_type = type_id->type;
PTreeFree( type_id );
dinfo = makeDeclInfo( NULL );
dinfo->type = new_type;
return( dinfo );
}
static boolean dupCompare( TYPE test1, TYPE test2 )
{
arg_list *args1;
arg_list *args2;
TYPE *p1;
TYPE *p2;
unsigned i;
/* check TypedefReset if TYP_TYPEDEFs are ever checked */
/* check typesBind/performBinding (in this module) if comparisons change */
/* check TYPECOMP.C if comparisons change */
switch( test1->id ) {
case TYP_BITFIELD:
if( test1->u.b.field_start != test2->u.b.field_start ) {
return( FALSE );
}
if( test1->u.b.field_width != test2->u.b.field_width ) {
return( FALSE );
}
break;
case TYP_FUNCTION:
if( test1->u.f.pragma != test2->u.f.pragma ) {
return( FALSE );
}
args1 = test1->u.f.args;
args2 = test2->u.f.args;
if( args1 == args2 ) {
return( TRUE );
}
if( args1->num_args != args2->num_args ) {
return( FALSE );
}
if( args1->qualifier != args2->qualifier ) {
return( FALSE );
}
p1 = args1->type_list;
p2 = args2->type_list;
for( i = args1->num_args; i != 0; --i ) {
if( *p1 != *p2 ) {
return( FALSE );
}
++p1;
++p2;
}
p1 = args1->except_spec;
p2 = args2->except_spec;
if( p1 != p2 ) {
TYPE tp1, tp2;
if( p1 == NULL || p2 == NULL ) {
return( FALSE );
}
for(;;) {
tp1 = *p1;
if( tp1 == NULL ) return FALSE;
tp2 = *p2;
if( tp2 == NULL ) return FALSE;
if( tp1 != tp2 ) return FALSE;
++p1;
++p2;
}
}
break;
case TYP_ARRAY:
if( test1->u.a.array_size != test2->u.a.array_size ) {
return( FALSE );
}
break;
case TYP_MODIFIER:
if( test1->u.m.base != test2->u.m.base ) {
return( FALSE );
}
if( test1->u.m.pragma != test2->u.m.pragma ) {
return( FALSE );
}
break;
case TYP_MEMBER_POINTER:
if( test1->u.mp.host != test2->u.mp.host ) {
return( FALSE );
}
break;
case TYP_GENERIC:
if( test1->u.g.index != test2->u.g.index ) {
return( FALSE );
}
break;
case TYP_ERROR:
if( test1->u.e.fmt != test2->u.e.fmt ) {
return( FALSE );
}
break;
case TYP_POINTER:
break;
default:
#ifndef NDEBUG
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?