ctype.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,644 行 · 第 1/4 页

C
1,644
字号
/****************************************************************************
*
*                            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:  Type management functions.
*
****************************************************************************/


#include "cvars.h"

extern  unsigned SymTypedef;

extern FIELDPTR FieldCreate( char *name );

local TYPEPTR StructDecl(int,int);
//local TYPEPTR ComplexDecl(int,int);
static void SetPlainCharType( int char_type );
local void CheckBitfieldType( TYPEPTR typ );

#if _CPU == 386
#define _CHECK_SIZE( s )
#else
#define _CHECK_SIZE( s ) \
        if( (s) > 0xffff ) {\
            CErr1( ERR_MAX_STRUCT_SIZE_IS_64K );\
        }
#endif

/* matches enum DataType in ctypes.h */
static  char    CTypeSizes[TYPE_LAST_ENTRY] = {
    TARGET_CHAR,        /* CHAR                     */
    TARGET_CHAR,        /* UCHAR                    */
    TARGET_SHORT,       /* SHORT                    */
    TARGET_SHORT,       /* USHORT                   */
    TARGET_INT,         /* INT                      */
    TARGET_INT,         /* UINT                     */
    TARGET_LONG,        /* LONG                     */
    TARGET_LONG,        /* ULONG                    */
    TARGET_LONG64,      /* LONGLONG                 */
    TARGET_LONG64,      /* ULONGLONG                */
    TARGET_FLOAT,       /* FLOAT                    */
    TARGET_DOUBLE,      /* DOUBLE                   */
    TARGET_LDOUBLE,     /* LONG DOUBLE              */
    TARGET_FIMAGINARY,  /* FLOAT IMAGINARY          */
    TARGET_DIMAGINARY,  /* DOUBLE IMAGINARY         */
    TARGET_LDIMAGINARY, /* LONG DOUBLE IMAGINARY    */
    TARGET_BOOL,        /* BOOL                     */
    0, /*TARGET_POINTER,*/ /* POINTER               */
    0,                  /* ARRAY                    */
    0,                  /* STRUCT                   */
    0,                  /* UNION                    */
    0,                  /* FUNCTION                 */
    0,                  /* FIELD                    */
    0, /*TARGET_CHAR,*/ /* VOID                     */
    0,                  /* ENUM                     */
    0,                  /* TYPEDEF                  */
    0,                  /* UFIELD                   */
    0,                  /* DOT_DOT_DOT              */
    TARGET_CHAR,        /* PLAIN_CHAR               */
    TARGET_WCHAR,       /* WCHAR                    */
    TARGET_FCOMPLEX,    /* FLOAT COMPLEX            */
    TARGET_DCOMPLEX,    /* DOUBLE COMPLEX           */
    TARGET_LDCOMPLEX,   /* LONG DOUBLE COMPLEX      */
};

TYPEPTR CTypeHash[TYPE_LAST_ENTRY];
TYPEPTR PtrTypeHash[TYPE_LAST_ENTRY];

TAGPTR  TagHash[TAG_HASH_SIZE + 1];
FIELDPTR FieldHash[FIELD_HASH_SIZE];

enum {
        M_CHAR          = 0x0001,
        M_INT           = 0x0002,
        M_SHORT         = 0x0004,
        M_LONG          = 0x0008,
        M_SIGNED        = 0x0010,
        M_UNSIGNED      = 0x0020,
        M_FLOAT         = 0x0040,
        M_DOUBLE        = 0x0080,
        M_LONG_LONG     = 0x0100,
        M_VOID          = 0x0200,
        M_COMPLEX       = 0x0400,
        M_IMAGINARY     = 0x0800,
        M_BOOL          = 0x1000,
        M___LAST        = 0
 };

#define TYPE_PLAIN_INT  TYPE_UFIELD                     /* 19-mar-91 */

signed char Valid_Types[] = {
        -1,             //
        TYPE_PLAIN_CHAR,//                                          M_CHAR
        TYPE_PLAIN_INT, //                                    M_INT
        -1,             //                                    M_INT M_CHAR
        TYPE_SHORT,     //                            M_SHORT
        -1,             //                            M_SHORT       M_CHAR
        TYPE_SHORT,     //                            M_SHORT M_INT
        -1,             //                            M_SHORT M_INT M_CHAR
        TYPE_LONG,      //                     M_LONG
        -1,             //                     M_LONG               M_CHAR
        TYPE_LONG,      //                     M_LONG         M_INT
        -1,             //                     M_LONG         M_INT M_CHAR
        -1,             //                     M_LONG M_SHORT
        -1,             //                     M_LONG M_SHORT       M_CHAR
        -1,             //                     M_LONG M_SHORT M_INT
        -1,             //                     M_LONG M_SHORT M_INT M_CHAR
        TYPE_INT,       //            M_SIGNED
        TYPE_CHAR,      //            M_SIGNED                      M_CHAR
        TYPE_INT,       //            M_SIGNED                M_INT
        -1,             //            M_SIGNED                M_INT M_CHAR
        TYPE_SHORT,     //            M_SIGNED        M_SHORT
        -1,             //            M_SIGNED        M_SHORT       M_CHAR
        TYPE_SHORT,     //            M_SIGNED        M_SHORT M_INT
        -1,             //            M_SIGNED        M_SHORT M_INT M_CHAR
        TYPE_LONG,      //            M_SIGNED M_LONG
        -1,             //            M_SIGNED M_LONG               M_CHAR
        TYPE_LONG,      //            M_SIGNED M_LONG         M_INT
        -1,             //            M_SIGNED M_LONG         M_INT M_CHAR
        -1,             //            M_SIGNED M_LONG M_SHORT
        -1,             //            M_SIGNED M_LONG M_SHORT       M_CHAR
        -1,             //            M_SIGNED M_LONG M_SHORT M_INT
        -1,             //            M_SIGNED M_LONG M_SHORT M_INT M_CHAR
        TYPE_UINT,      // M_UNSIGNED
        TYPE_UCHAR,     // M_UNSIGNED                               M_CHAR
        TYPE_UINT,      // M_UNSIGNED                         M_INT
        -1,             // M_UNSIGNED                         M_INT M_CHAR
        TYPE_USHORT,    // M_UNSIGNED                 M_SHORT
        -1,             // M_UNSIGNED                 M_SHORT       M_CHAR
        TYPE_USHORT,    // M_UNSIGNED                 M_SHORT M_INT
        -1,             // M_UNSIGNED                 M_SHORT M_INT M_CHAR
        TYPE_ULONG,     // M_UNSIGNED          M_LONG
        -1,             // M_UNSIGNED          M_LONG               M_CHAR
        TYPE_ULONG,     // M_UNSIGNED          M_LONG         M_INT
        -1,             // M_UNSIGNED          M_LONG         M_INT M_CHAR
        -1,             // M_UNSIGNED          M_LONG M_SHORT
        -1,             // M_UNSIGNED          M_LONG M_SHORT       M_CHAR
        -1,             // M_UNSIGNED          M_LONG M_SHORT M_INT
        -1,             // M_UNSIGNED          M_LONG M_SHORT M_INT M_CHAR
        -1,             // M_UNSIGNED M_SIGNED
        -1,             // M_UNSIGNED M_SIGNED                      M_CHAR
        -1,             // M_UNSIGNED M_SIGNED                M_INT
        -1,             // M_UNSIGNED M_SIGNED                M_INT M_CHAR
        -1,             // M_UNSIGNED M_SIGNED        M_SHORT
        -1,             // M_UNSIGNED M_SIGNED        M_SHORT       M_CHAR
        -1,             // M_UNSIGNED M_SIGNED        M_SHORT M_INT
        -1,             // M_UNSIGNED M_SIGNED        M_SHORT M_INT M_CHAR
        -1,             // M_UNSIGNED M_SIGNED M_LONG
        -1,             // M_UNSIGNED M_SIGNED M_LONG               M_CHAR
        -1,             // M_UNSIGNED M_SIGNED M_LONG         M_INT
        -1,             // M_UNSIGNED M_SIGNED M_LONG         M_INT M_CHAR
        -1,             // M_UNSIGNED M_SIGNED M_LONG M_SHORT
        -1,             // M_UNSIGNED M_SIGNED M_LONG M_SHORT       M_CHAR
        -1,             // M_UNSIGNED M_SIGNED M_LONG M_SHORT M_INT
        -1,             // M_UNSIGNED M_SIGNED M_LONG M_SHORT M_INT M_CHAR
};

void InitTypeHashTables( void )
{
    int         index;
    int         base_type;

    for( index = 0; index <= MAX_PARM_LIST_HASH_SIZE; ++index ) {
        FuncTypeHead[ index ] = NULL;
    }
    for( base_type = TYPE_CHAR; base_type < TYPE_LAST_ENTRY; ++base_type ) {
        CTypeHash[ base_type ] = NULL;
        PtrTypeHash[ base_type ] = NULL;
    }
    for( index = 0; index <= TAG_HASH_SIZE; ++index ) {
        TagHash[ index ] = NULL;
    }
    for( index = 0; index < FIELD_HASH_SIZE; ++index ) {
        FieldHash[ index ] = NULL;
    }
}

void CTypeInit( void )
{
    DATA_TYPE   base_type;
    int         size;

    TypeHead = NULL;
    TagCount = 0;
    FieldCount = 0;
    EnumCount = 0;
    InitTypeHashTables();
    for( base_type = TYPE_CHAR; base_type < TYPE_LAST_ENTRY; ++base_type ) {
        CTypeCounts[ base_type ] = 0;
        size = CTypeSizes[ base_type ];
        /*
        if ( base_type == TYPE_FCOMPLEX || base_type == TYPE_DCOMPLEX
                            || base_type == TYPE_LDCOMPLEX ) {
            BaseTypes[ base_type ] = ComplexDecl( TYPE_STRUCT, FALSE );
            BaseTypes[ base_type ]->decl_type = base_type;
        } else
        */
        if( size != 0  ||  base_type == TYPE_VOID  ||
                            base_type == TYPE_DOT_DOT_DOT ) {
            BaseTypes[ base_type ] = TypeNode( base_type, NULL );
        } else {
            BaseTypes[ base_type ] = NULL;
        }
    }
    SetPlainCharType( TYPE_UCHAR );
    StringArrayType = NULL;
    VoidParmList[0] = BaseTypes[ TYPE_VOID ];   /* 27-dec-88 */
    VoidParmList[1] = NULL;
}


TYPEPTR GetType( DATA_TYPE base_type )
{
    TYPEPTR     typ;

    typ = BaseTypes[ base_type ];
    if( typ == NULL ) {
        typ = TypeNode( base_type, NULL );
    }
    return( typ );
}

void WalkFuncTypeList( void (*func)(TYPEPTR,int) )
{
    TYPEPTR     typ;
    int         index;

    for( index = 0; index <= MAX_PARM_LIST_HASH_SIZE; index++ ) {
        for( typ = FuncTypeHead[ index ]; typ; typ = typ->next_type ) {
            func( typ, index );
        }
    }
}

void WalkTypeList( void (*func)(TYPEPTR) )
{
    TYPEPTR     typ;
    int         base_type;

    for( base_type = TYPE_CHAR; base_type < TYPE_LAST_ENTRY; ++base_type ) {
        for( typ = CTypeHash[ base_type ]; typ; typ = typ->next_type ) {
            func( typ );
        }
    }
    for( base_type = TYPE_CHAR; base_type < TYPE_LAST_ENTRY; ++base_type ) {
        for( typ = PtrTypeHash[ base_type ]; typ; typ = typ->next_type ) {
            func( typ );
        }
    }
}

TYPEPTR DupType( TYPEPTR typ, enum type_state flags, bool force_duplicate )
{
    TYPEPTR     newtype;
    TYPEPTR     next;

    if( !force_duplicate ) {
        if( typ->decl_type == TYPE_POINTER ) {
            next = PtrTypeHash[ typ->object->decl_type ];
        } else {
            next = CTypeHash[ typ->decl_type ];
        }
        for( ; next; next = next->next_type ) {
            if( next->decl_type  == typ->decl_type  &&
                next->object     == typ->object     &&
                next->u.tag      == typ->u.tag      &&
                next->type_flags == flags ) {
                return( next );
            }
        }
    }
    newtype = TypeNode( typ->decl_type, typ->object );
    next = newtype->next_type;
    memcpy( newtype, typ, sizeof( TYPEDEFN ) );
    newtype->next_type = next;
    newtype->type_flags = flags;
    return( newtype );
}

static void SetPlainCharType( int char_type )
{
    TYPEPTR     typ;

    typ = TypeNode( char_type, NULL );
    typ->type_flags = TF2_TYPE_PLAIN_CHAR;
    BaseTypes[ TYPE_PLAIN_CHAR ] = typ;
    StringType = PtrNode( typ, FLAG_NONE, SEG_DATA );
    ConstCharType =  typ;
}

void SetSignedChar( void )
{
    SetPlainCharType( TYPE_CHAR );
}


int TypeQualifier( void )
{
    type_modifiers   flags, bit;

    flags = 0;
    bit = 0;
    for( ;; ) {
        if( flags & bit )  CErr1( ERR_REPEATED_MODIFIER );       /* 24-mar-91 */
        flags |= bit;
        if( CurToken == T_CONST ) {
            bit = FLAG_CONST;
            NextToken();
            continue;
        }
        if( CurToken == T_VOLATILE ) {
            bit = FLAG_VOLATILE;
            NextToken();
            continue;
        }
        if( CurToken == T_RESTRICT || CurToken == T___RESTRICT ) {
            bit = FLAG_RESTRICT;
            NextToken();
            continue;
        }
        if( CurToken == T___UNALIGNED ) {
            bit = FLAG_UNALIGNED;
            NextToken();
            continue;
        }
        break;
    }
    return( flags );
}

local TYPEPTR GetScalarType( char *plain_int, int bmask, type_modifiers flags )
{
    DATA_TYPE   data_type;
    TYPEPTR     typ;

    data_type = TYPE_UNDEFINED;
    if( bmask & M_LONG_LONG ) {
        bmask &= ~M_INT;
    }
    if( bmask & (M_VOID | M_FLOAT | M_DOUBLE | M_LONG_LONG | M_COMPLEX | M_IMAGINARY) ) {
        if( bmask == M_VOID ) {
            data_type = TYPE_VOID;
        } else if( bmask == M_LONG_LONG ) {
            data_type = TYPE_LONG64;
        } else if( bmask == (M_LONG_LONG | M_SIGNED) ) {
            data_type = TYPE_LONG64;
        } else if( bmask == (M_LONG_LONG | M_UNSIGNED) ) {
            data_type = TYPE_ULONG64;
        } else if( bmask == M_FLOAT ) {
            data_type = TYPE_FLOAT;
        } else if( bmask == M_DOUBLE ) {
            data_type = TYPE_DOUBLE;
        } else if( bmask == (M_LONG | M_DOUBLE) ) {
            if( CompFlags.use_long_double )
                data_type = TYPE_LONG_DOUBLE;
            else
                data_type = TYPE_DOUBLE;

        } else if( bmask == (M_COMPLEX | M_FLOAT) ) {
            data_type = TYPE_FCOMPLEX;
        } else if( bmask == (M_COMPLEX | M_DOUBLE) ) {
            data_type = TYPE_DCOMPLEX;
        } else if( bmask == (M_COMPLEX | M_LONG | M_DOUBLE) ) {
            if( CompFlags.use_long_double )
                data_type = TYPE_LDCOMPLEX;
            else
                data_type = TYPE_DCOMPLEX;

        } else if( bmask == (M_IMAGINARY | M_FLOAT) ) {
            data_type = TYPE_FIMAGINARY;
        } else if( bmask == (M_IMAGINARY | M_DOUBLE) ) {
            data_type = TYPE_DIMAGINARY;
        } else if( bmask == (M_IMAGINARY | M_LONG | M_DOUBLE) ) {
            if( CompFlags.use_long_double )
                data_type = TYPE_LDIMAGINARY;
            else
                data_type = TYPE_DIMAGINARY;

        } else {
            data_type = TYPE_UNDEFINED;
        }
    } 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 ];

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?