ctype.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,644 行 · 第 1/4 页
C
1,644 行
if( data_type == TYPE_PLAIN_INT ) { /* 19-mar-91 */
data_type = TYPE_INT;
*plain_int = 1;
}
}
if( data_type == TYPE_UNDEFINED ) {
CErr1( ERR_INV_TYPE );
data_type = TYPE_INT;
}
typ = GetType( data_type );
if( flags & FLAG_SEGMENT )
typ = DupType( typ, TF2_TYPE_SEGMENT, FALSE );
return( typ );
}
local void AdvanceToken( void )
{
if( CurToken == T_SAVED_ID ) {
CMemFree( SavedId );
SavedId = NULL;
CurToken = LAToken;
} else {
NextToken();
}
}
static void DeclSpecifiers( char *plain_int, decl_info *info )
{
TYPEPTR typ;
int bmask;
int bit;
type_modifiers flags;
int packed;
SYM_HANDLE sym_handle;
stg_classes stg_class;
stg_classes specified_stg_class;
auto SYM_ENTRY sym;
*plain_int = 0;
info->mod = FLAG_NONE;
info->decl_mod = FLAG_NONE;
info->decl = DECLSPEC_NONE;
info->naked = FALSE;
info->seg = 0;
bmask = 0;
flags = FLAG_NONE;
packed = FALSE;
typ = NULL;
specified_stg_class = SC_NULL;
for(;;) {
stg_class = SC_NULL;
bit = 0;
switch( CurToken ) {
case T_CHAR: bit = M_CHAR; break;
case T_INT: bit = M_INT; break;
case T_SHORT: bit = M_SHORT; break;
case T_LONG: bit = M_LONG; break;
case T___INT64: bit = M_LONG_LONG; break;
case T_SIGNED: bit = M_SIGNED; break;
case T_UNSIGNED: bit = M_UNSIGNED; break;
case T_FLOAT: bit = M_FLOAT; break;
case T_DOUBLE: bit = M_DOUBLE; break;
case T_VOID: bit = M_VOID; break;
case T__COMPLEX: bit = M_COMPLEX; break;
case T__IMAGINARY:bit = M_IMAGINARY; break;
case T__BOOL: bit = M_BOOL; break;
case T_CONST:
if( flags & FLAG_CONST )
CErr1( ERR_REPEATED_MODIFIER );
flags |= FLAG_CONST;
break;
case T_VOLATILE:
if( flags & FLAG_VOLATILE )
CErr1( ERR_REPEATED_MODIFIER );
flags |= FLAG_VOLATILE;
break;
case T_RESTRICT:
case T___RESTRICT:
if( flags & FLAG_RESTRICT )
CErr1( ERR_REPEATED_MODIFIER );
flags |= FLAG_RESTRICT;
break;
case T___UNALIGNED:
if( flags & FLAG_UNALIGNED )
CErr1( ERR_REPEATED_MODIFIER );
flags |= FLAG_UNALIGNED;
break;
case T_INLINE:
case T___INLINE:
flags |= FLAG_INLINE;
break;
case T__PACKED:
if( packed )
CErr1( ERR_REPEATED_MODIFIER );
packed = TRUE;
break;
case T_EXTERN:
stg_class = SC_EXTERN;
break;
case T_STATIC:
stg_class = SC_STATIC;
break;
case T_TYPEDEF:
stg_class = SC_TYPEDEF;
break;
case T_AUTO:
stg_class = SC_AUTO;
break;
case T_REGISTER:
stg_class = SC_REGISTER;
break;
case T_STRUCT:
if( typ != NULL )
CErr1( ERR_INV_TYPE );
typ = StructDecl( TYPE_STRUCT, packed );
packed = 0;
continue;
case T_UNION:
if( typ != NULL )
CErr1( ERR_INV_TYPE );
typ = StructDecl( TYPE_UNION, packed );
packed = 0;
continue;
case T_ENUM:
if( typ != NULL )
CErr1( ERR_INV_TYPE );
typ = EnumDecl( flags );
continue;
case T___SEGMENT: /* 21-oct-91 */
bit = M_UNSIGNED | M_SHORT;
flags |= FLAG_SEGMENT; /* 15-nov-91 */
break;
case T___DECLSPEC:
AdvanceToken(); // declspec( dllimport naked )
MustRecog( T_LEFT_PAREN );
{
declspec_class decl;
type_modifiers modifier;
while( CurToken != T_RIGHT_PAREN ) {
modifier = 0;
switch( CurToken ) {
case T___WATCALL:
modifier = LANG_WATCALL;
break;
case T__CDECL:
case T___CDECL:
modifier = LANG_CDECL;
break;
case T__PASCAL:
case T___PASCAL:
modifier = LANG_PASCAL;
break;
case T___FORTRAN:
modifier = LANG_FORTRAN;
break;
case T__SYSCALL:
case T___SYSCALL:
case T__SYSTEM:
modifier = LANG_SYSCALL;
break;
case T___STDCALL:
modifier = LANG_STDCALL;
break;
case T__FASTCALL:
case T___FASTCALL:
modifier = LANG_FASTCALL;
break;
case T__OPTLINK:
modifier = LANG_OPTLINK;
break;
case T_ID:
decl = DECLSPEC_NONE;
if( info->stg == 0 ) {
CErr1( ERR_INVALID_DECLARATOR );
break;
}
if( strcmp( Buffer, "dllimport" ) == 0 ) {
decl = DECLSPEC_DLLIMPORT;
} else if( strcmp( Buffer, "overridable" ) == 0 ) {
decl = DECLSPEC_DLLIMPORT;
} else if( strcmp( Buffer, "dllexport" ) == 0 ) {
decl = DECLSPEC_DLLEXPORT;
} else if( strcmp( Buffer, "thread" ) == 0 ) {
decl = DECLSPEC_THREAD;
} else if( strcmp( Buffer, "naked" ) == 0 ) {
if( info->naked ) {
CErr1( ERR_INVALID_DECLSPEC );
} else {
info->naked = TRUE;
}
} else {
CErr1( ERR_INVALID_DECLSPEC );
}
if( decl != DECLSPEC_NONE ) {
if( info->decl == DECLSPEC_NONE ) {
info->decl = decl;
} else {
CErr1( ERR_INVALID_DECLSPEC );
}
}
break;
default:
CErr1( ERR_INVALID_DECLSPEC );
goto done;
}
if( modifier & FLAG_LANGUAGES ) {
if( info->decl_mod & FLAG_LANGUAGES ) {
CErr1( ERR_INVALID_DECLSPEC );
} else {
info->decl_mod |= modifier;
}
}
NextToken();
}
}
done:
MustRecog( T_RIGHT_PAREN );
continue;
case T_SAVED_ID:
case T_ID:
if( typ != NULL || bmask != 0 ) goto got_specifier;
/* lookup id in symbol table */
/* if valid type identifier then OK */
if( CurToken == T_ID ) {
sym_handle = SymLookTypedef( HashValue, Buffer, &sym );
} else { /* T_SAVED_ID */
sym_handle = SymLookTypedef( SavedHash, SavedId, &sym );
}
if( sym_handle == 0 ) goto got_specifier;
if( sym.stg_class != SC_TYPEDEF ) goto got_specifier;
if( SymLevel != 0 && flags == 0 ) {
if( CurToken == T_ID ) {
LookAhead();
if( LAToken == T_COLON ) goto got_specifier;
}
}
++SymTypedef;
typ = sym.sym_type;
SymGet( &sym, sym_handle ); // get rest of sym from nutty sym table
if( flags & sym.attrib ) { /* 24-mar-91, 12-may-91 */
CErr1( ERR_INV_TYPE );
}
flags |= sym.attrib;
if( sym.attrib & FLAG_BASED ) {
info->seg = sym.u.var.segment;
}
if( sym.declspec != DECLSPEC_NONE ) {
if( info->decl == DECLSPEC_NONE ) {
info->decl = sym.declspec;
} else {
CErr1( ERR_INVALID_DECLSPEC );
}
}
if( sym.naked ) {
if( info->naked ) {
CErr1( ERR_INVALID_DECLSPEC );
} else {
info->naked = TRUE;
}
}
AdvanceToken();
continue;
default: goto got_specifier;
}
if( stg_class != SC_NULL ) {
if( info->stg == SC_NULL ) break; // don't want any stg class
if( specified_stg_class != SC_NULL ) {
CErr1( ERR_TOO_MANY_STORAGE_CLASS_SPECIFIERS );
}
specified_stg_class = stg_class;
}
if( bmask & bit ) {
if( bit == M_LONG ) {
// long long found
bmask &= ~M_LONG;
bit = M_LONG_LONG;
} else {
CErr1( ERR_INV_TYPE );
}
}
bmask |= bit;
NextToken();
}
got_specifier:
info->stg = specified_stg_class;
if( typ != NULL ) {
/* already have a type (TYPE_STRUCT, TYPE_UNION, TYPE_ENUM) */
/* or an ID that was a typedef name */
if( bmask != 0 ) CErr1( ERR_INV_TYPE ); // picked up an int
} else {
if( flags != FLAG_NONE || bmask != 0 ) { // not just id hanging there
typ = GetScalarType( plain_int, bmask, flags );
}
}
info->typ = typ;
info->mod = flags;
}
void TypeSpecifier( decl_info *info )
{
char plain_int;
info->stg = SC_NULL; // indicate don't want any storage class specifiers
DeclSpecifiers( &plain_int, info );
}
void GetFieldTypeSpecifier( char *plain_int, decl_info *info )
{
info->stg = SC_NULL; // indicate don't want any storage class specifiers
DeclSpecifiers( plain_int, info );
}
void FullDeclSpecifier( decl_info *info )
{
char plain_int;
info->stg = SC_FORWARD; // indicate want storage class specifiers
DeclSpecifiers( &plain_int, info );
}
TYPEPTR TypeDefault( void )
{
return( GetType( TYPE_INT ) );
}
static TAGPTR NewTag( char *name, int hash )
{
TAGPTR tag;
tag = (TAGPTR) CPermAlloc( sizeof( TAGDEFN ) + strlen( name ) );
tag->level = SymLevel;
tag->hash = hash;
tag->next_tag = TagHash[ hash ];
TagHash[ hash ] = tag;
strcpy( tag->name, name );
++TagCount;
return( tag );
}
TAGPTR NullTag( void )
{
return( NewTag( "", TAG_HASH_SIZE ) );
}
TAGPTR VfyNewTag( TAGPTR tag, int tag_type )
{
if( tag->sym_type != NULL ) { /* tag already exists */
if( tag->level != SymLevel ) {
tag = NewTag( tag->name, tag->hash );
} else if( tag->size != 0 || /* already defined */
tag->sym_type->decl_type != tag_type ) { /* 18-jan-89 */
CErr2p( ERR_DUPLICATE_TAG, tag->name );
}
}
return( tag );
}
local FIELDPTR NewField( FIELDPTR new_field, TYPEPTR decl )
{
FIELDPTR field;
FIELDPTR prev_field;
TYPEPTR typ;
TAGPTR tag;
++FieldCount;
typ = new_field->field_type;
if( typ != NULL ) {
SKIP_TYPEDEFS( typ );
}
if( new_field->name[0] == '\0' ) {
/* allow nameless structs and unions; 15-sep-90 */
if( (typ->decl_type != TYPE_STRUCT &&
typ->decl_type != TYPE_UNION) ||
! CompFlags.extensions_enabled ) {
CErr1( ERR_INVALID_DECLARATOR );
}
}
if( typ == decl ) {
CErr1( ERR_STRUCT_OR_UNION_INSIDE_ITSELF );
} else if( SizeOfArg( typ ) == 0 ) { /* was TypeSize(typ) 15-may-90*/
/* can't have an array of incomplete type 24-aug-90 */
if( (typ->decl_type == TYPE_ARRAY &&
(SizeOfArg( typ->object ) == 0 || !CompFlags.extensions_enabled ) )
|| typ->decl_type != TYPE_ARRAY ) { /* JFD 15-jun-90 */
CErr( ERR_INCOMPLETE_TYPE, (SYM_NAMEPTR)(new_field->name) );
}
}
tag = decl->u.tag;
new_field->hash = HashValue;
if( new_field->name[0] != '\0' ) { /* only check non-empty names */
for( field = FieldHash[HashValue]; field;
field = field->next_field_same_hash ) {
/* fields were added at the front of the hash linked list --
may as well stop if the level isn't the same anymore */
if( field->level != new_field->level )
break;
if( strcmp( field->name, new_field->name ) == 0 ) {
CErr2p( ERR_DUPLICATE_FIELD_NAME, field->name );
}
}
new_field->next_field_same_hash = FieldHash[HashValue];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?