typecomp.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 371 行
C
371 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include "plusplus.h"
#include "errdefns.h"
#include "carve.h"
#include "template.h"
#include "pragdefn.h"
#include "initdefs.h"
typedef struct tc_data TC_DATA;
struct tc_data {
TC_DATA *next;
TYPE type1;
TYPE type2;
unsigned arg_index;
type_exclude mask;
enum {
FUNCTION,
MEMBER_POINTER
} flavour;
};
typedef enum {
FOLLOW_OF,
FOLLOW_STACK
} TC_STATE;
#define BLOCK_TC_DATA 32
static carve_t carveTC_DATA;
static TC_DATA *pushTC_DATA( TC_DATA **h )
{
return StackCarveAlloc( carveTC_DATA, h );
}
static void popTC_DATA( TC_DATA **h )
{
TC_DATA *e;
e = *h;
*h = e->next;
CarveFree( carveTC_DATA, e );
}
static boolean typeCompareCurrent( TC_DATA **h, TYPE type1, TYPE type2,
type_exclude mask )
{
type_flag flag1;
type_flag flag2;
arg_list *args1;
arg_list *args2;
TC_DATA *top;
if( type1 == NULL ) {
return( FALSE );
}
if( type2 == NULL ) {
return( FALSE );
}
if( type1->id != type2->id ) {
return( FALSE );
}
flag1 = type1->flag;
flag2 = type2->flag;
switch( type1->id ) {
case TYP_SINT:
case TYP_VOID:
break;
case TYP_ERROR:
case TYP_BOOL:
case TYP_CHAR:
case TYP_SCHAR:
case TYP_UCHAR:
case TYP_WCHAR:
case TYP_SSHORT:
case TYP_USHORT:
case TYP_UINT:
case TYP_SLONG:
case TYP_ULONG:
case TYP_SLONG64:
case TYP_ULONG64:
case TYP_FLOAT:
case TYP_DOUBLE:
case TYP_LONG_DOUBLE:
case TYP_POINTER:
case TYP_DOT_DOT_DOT:
if( flag1 != flag2 ) {
return( FALSE );
}
break;
case TYP_CLASS:
if( flag1 != flag2 || ( flag1 & TF1_UNBOUND ) == 0 ) {
return( FALSE );
}
return( TemplateUnboundSame( type1, type2 ) );
case TYP_ENUM:
return( FALSE );
case TYP_TYPEDEF:
if( flag1 != flag2 ) {
return( FALSE );
}
if( type1->u.t.sym != type2->u.t.sym ) {
return( FALSE );
}
if( type1->u.t.scope != type2->u.t.scope ) {
return( FALSE );
}
break;
case TYP_BITFIELD:
if( flag1 != flag2 ) {
return( FALSE );
}
if( type1->u.b.field_start != type2->u.b.field_start ) {
return( FALSE );
}
if( type1->u.b.field_width != type2->u.b.field_width ) {
return( FALSE );
}
break;
case TYP_FUNCTION:
if( mask & TC1_FUN_LINKAGE ) {
flag1 &= ~(TF1_PLUSPLUS | TF1_FN_IGNORE);
flag2 &= ~(TF1_PLUSPLUS | TF1_FN_IGNORE);
} else {
flag1 &= ~TF1_FN_IGNORE;
flag2 &= ~TF1_FN_IGNORE;
}
if( flag1 != flag2 ) {
return( FALSE );
}
if( ( type1->u.f.pragma != type2->u.f.pragma )
&&( ! PragmasTypeEquivalent( type1->u.f.pragma
, type2->u.f.pragma ) ) ) {
return( FALSE );
}
args1 = type1->u.f.args;
args2 = type2->u.f.args;
if( args1 != args2 ) {
if( args1 == NULL ) {
return( FALSE );
}
if( args2 == NULL ) {
return( FALSE );
}
if( args1->num_args != args2->num_args ) {
return( FALSE );
}
if( args1->qualifier != args2->qualifier ) {
return( FALSE );
}
if( args1->num_args > 0 ) {
top = pushTC_DATA( h );
top->type1 = type1;
top->type2 = type2;
top->arg_index = args1->num_args;
top->flavour = FUNCTION;
top->mask = mask | TC1_PTR_FUN;
}
}
break;
case TYP_ARRAY:
if( flag1 != flag2 ) {
return( FALSE );
}
if( type1->u.a.array_size != type2->u.a.array_size ) {
return( FALSE );
}
break;
case TYP_MODIFIER:
if( flag1 != flag2 ) {
return( FALSE );
}
if( type1->u.m.base != type2->u.m.base ) {
return( FALSE );
}
if( type1->u.m.pragma != type2->u.m.pragma ) {
return( FALSE );
}
break;
case TYP_MEMBER_POINTER:
if( flag1 != flag2 ) {
return( FALSE );
}
top = pushTC_DATA( h );
top->type1 = type1;
top->type2 = type2;
top->arg_index = 0;
top->flavour = MEMBER_POINTER;
top->mask = mask | TC1_PTR_FUN;
break;
case TYP_GENERIC:
if( flag1 != flag2 ) {
return( FALSE );
}
if( type1->u.g.index != type2->u.g.index ) {
return( FALSE );
}
break;
default:
#ifndef NDEBUG
CFatal( "unknown type being compared" );
#else
return( FALSE );
#endif
}
return( TRUE );
}
boolean TypeCompareExclude( TYPE type1, TYPE type2, type_exclude mask )
/*********************************************************************/
{
TC_STATE state;
type_flag flag1;
type_flag flag2;
void *base1;
void *base2;
TC_DATA *stack;
if( type1 == type2 ) {
return( TRUE );
}
stack = NULL;
state = FOLLOW_OF;
for(;;) {
if( type1 == NULL || type2 == NULL ) break;
// tweak type1 and type2 to ignore minor distinctions
type1 = TypeModExtract( type1, &flag1, &base1, mask|TC1_NOT_MEM_MODEL );
type2 = TypeModExtract( type2, &flag2, &base2, mask|TC1_NOT_MEM_MODEL );
if( type1 == NULL || type2 == NULL ) break;
if( mask & TC1_PTR_FUN ) {
type_flag extra;
// tweak type1 and type2 to ignore more major distinction
if( ( type1->id == TYP_POINTER )
&&( type2->id == TYP_FUNCTION ) ) {
type2 = TypeModFlagsEC( MakePointerTo( type2 ), &extra );
flag2 |= extra;
} else if( ( type2->id == TYP_POINTER )
&&( type1->id == TYP_FUNCTION ) ) {
type1 = TypeModFlagsEC( MakePointerTo( type1 ), &extra );
flag1 |= extra;
}
}
// compare type1 and type2
flag1 &= ~TF1_MOD_IGNORE;
flag2 &= ~TF1_MOD_IGNORE;
if( flag1 != flag2 ) {
break;
} else if( (flag1 & TF1_BASED) &&
!TypeBasesEqual( flag1, base1, base2 ) ) {
break;
} else if( type1 == type2 ) {
state = FOLLOW_STACK;
} else if( !typeCompareCurrent( &stack, type1, type2, mask ) ) {
break;
}
// advance the type pointers
for( ; ; ) {
TC_DATA *top;
unsigned arg_index;
switch( state ) {
case FOLLOW_OF:
type1 = type1->of;
type2 = type2->of;
break;
case FOLLOW_STACK:
top = stack;
if( top == NULL ) {
return( TRUE );
}
state = FOLLOW_OF;
switch( top->flavour ) {
case FUNCTION:
arg_index = --top->arg_index;
type1 = top->type1->u.f.args->type_list[arg_index];
type2 = top->type2->u.f.args->type_list[arg_index];
mask = top->mask;
if( arg_index == 0 ) {
popTC_DATA( &stack );
}
break;
case MEMBER_POINTER:
type1 = top->type1->u.mp.host;
type2 = top->type2->u.mp.host;
mask = top->mask;
popTC_DATA( &stack );
break;
}
break;
}
if( type1 == type2 ) {
state = FOLLOW_STACK;
continue;
}
break;
}
}
while( stack != NULL ) {
popTC_DATA( &stack );
}
return( FALSE );
}
boolean TypesSameExclude( TYPE type1, TYPE type2, type_exclude mask )
/*******************************************************************/
{
return( TypeCompareExclude( type1, type2, mask | TC1_PTR_FUN ) );
}
boolean TypesIdentical( TYPE type1, TYPE type2 )
/**********************************************/
{
return TypeCompareExclude( type1
, type2
, TC1_PTR_FUN | TC1_NOT_ENUM_CHAR );
}
static void typeCompareInit( // INITIALIZATION
INITFINI* defn ) // - definition
{
defn = defn;
carveTC_DATA = CarveCreate( sizeof( TC_DATA ), BLOCK_TC_DATA );
}
static void typeCompareFini( // COMPLETION
INITFINI* defn ) // - definition
{
defn = defn;
#ifndef NDEBUG
CarveVerifyAllGone( carveTC_DATA, "TC_DATA" );
#endif
CarveDestroy( carveTC_DATA );
}
INITDEFN( type_compare, typeCompareInit, typeCompareFini );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?