📄 ctype.c
字号:
data_type = TYPE_LDIMAGINARY;
else
data_type = TYPE_DIMAGINARY;
} else {
data_type = -1;
}
} else if( bmask == M_BOOL ) {
data_type = TYPE_BOOL;
} else if( bmask == 0 ) {
data_type = TYPE_INT;
*plain_int = 1;
} else {
data_type = Valid_Types[ bmask ];
if( data_type == TYPE_PLAIN_INT ) { /* 19-mar-91 */
data_type = TYPE_INT;
*plain_int = 1;
}
}
if( data_type == -1 ) {
CErr1( ERR_INV_TYPE );
data_type = TYPE_INT;
}
typ = GetType( data_type );
return( typ );
}
local void AdvanceToken()
{
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;
int 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 = 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:
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:
if( info->stg == 0 ){
CErr1( ERR_INVALID_DECLARATOR );
}
AdvanceToken(); // declspec( dllimport naked )
MustRecog( T_LEFT_PAREN );
{
declspec_class decl;
type_modifiers modifier;
decl = DECLSPEC_NONE;
modifier = 0;
while( CurToken != T_RIGHT_PAREN ){
switch( CurToken ){
case T___CDECL:
modifier = LANG_CDECL;
break;
case T___PASCAL:
modifier = LANG_PASCAL;
break;
case T___FORTRAN:
modifier = LANG_FORTRAN; // TC_FORTRAN
break;
case T__SYSCALL:
modifier = LANG_SYSCALL; // TC_SYSCALL /* 04-jul-91 */
break;
case T___STDCALL:
modifier = LANG_STDCALL; // TC_STDCALL
break;
case T___FASTCALL:
modifier = LANG_FASTCALL; // TC_FASTCALL
break;
case T__OPTLINK:
modifier = LANG_OPTLINK; // TC_OPTLINK
break;
case T_ID:
decl = DECLSPEC_NONE;
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( flags & FLAG_LANGUAGES ){
CErr1( ERR_INVALID_DECLSPEC );
}else{
flags |= 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 );
}
}
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()
{
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()
{
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 ) {
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
}
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -