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 + -
显示快捷键?