⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctype.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
                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 + -