type.c

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

C
2,314
字号
/****************************************************************************
*
*                            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:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


/*
TYPE: C++ type system
*/
#include "plusplus.h"

#include <stddef.h>
#include <stdarg.h>
#include <assert.h>

#include "memmgr.h"
#include "errdefns.h"
#include "ptree.h"
#include "cgfront.h"
#include "ring.h"
#include "carve.h"
#include "preproc.h"
#include "dbg.h"
#include "class.h"
#include "name.h"
#include "toggle.h"
#include "fnovload.h"
#include "fnbody.h"
#include "pragdefn.h"
#include "rewrite.h"
#include "codegen.h"
#include "defarg.h"
#include "vstk.h"
#include "pstk.h"
#include "template.h"
#include "initdefs.h"
#include "pcheader.h"
#include "stats.h"
#include "objmodel.h"
#include "cdopt.h"
#include "fmttype.h"
#include "dwarfdbg.h"
#include "rtti.h"

#define TYPE_HASH_MODULUS       (1<<5)  // modulus when type hashed
#define TYPE_HASH_MASK          (TYPE_HASH_MODULUS-1)// mask for above modulus
#define ARGS_HASH               8       // max arg.s for fn.s hashing
#define ARGS_MAX                16      // max arg.s for fn.s lists

#define zero_table( table ) memset( table, 0, sizeof( table ) )

TYPE TypeError;
TYPE TypeCache[ TYPC_LAST ];

static TYPE basicTypes[TYP_MAX];
static TYPE typeTable[TYP_MAX];
static TYPE fnHashTable[ARGS_HASH][TYPE_HASH_MODULUS];
static TYPE fnTable[ARGS_MAX-ARGS_HASH];
static TYPE pointerHashTable[TYPE_HASH_MODULUS];
static TYPE bitfieldHashTable[TYPE_HASH_MODULUS];
static TYPE arrayHashTable[TYPE_HASH_MODULUS];
static TYPE modifierHashTable[TYPE_HASH_MODULUS];
static TYPE* typeHashTables[TYP_MAX];
static TYPE uniqueTypes;
static AUX_INFO *cdeclPragma;
static type_flag defaultFunctionMemFlag;
static type_flag defaultDataMemFlag;
static unsigned typeHashCtr;

#define BLOCK_TYPE              64
#define BLOCK_DECL_SPEC         8
#define BLOCK_CLASSINFO         16
#define BLOCK_DECL_INFO         4

static carve_t carveTYPE;
static carve_t carveDECL_SPEC;
static carve_t carveCLASSINFO;
static carve_t carveDECL_INFO;

/* special member function checking return status */
enum {
    SM_RETURN_DECLARATOR        = 0x01, /* found return type declarators */
    SM_NOT_A_FUNCTION           = 0x02, /* found declarators before function */
    SM_CV_FUNCTION_ERROR        = 0x04, /* found () const/volatile use error */
                                        /* private flags (never returned) */
    SM_SAW_CV_FUNCTION          = 0x20, /* () const/volatile seen */
    SM_SAW_FUNCTION             = 0x40, /* function declarator seen */
    SM_SAW_DECLARATOR           = 0x80, /* non-function declarator seen */
    SM_NULL                     = 0x00
};

/* special id checking information */
enum {
    IDI_CLASS_TEMPLATE_MEMBER   = 0x01, /* id is a member of a class template */
    IDI_NULL                    = 0x00
};

enum {
    PA_MARK_FIRST_LEVEL         = 0x01,
    PA_NULL                     = 0x00
};

enum {
    TB_BINDS                    = 0x01,
    TB_NEEDS_TRIVIAL            = 0x02,
    TB_NEEDS_DERIVED            = 0x04,
    TB_NULL                     = 0x00
};

enum {
    MTT_INLINE                  = 0x01,
    MTT_COPY_PRAGMA             = 0x02,
    MTT_REUSE_ARGLIST           = 0x04,
    MTT_NULL                    = 0x00
};

enum {
    DF_REUSE_ARGLIST            = 0x01,
    DF_NULL                     = 0x00
};

enum {
    DA_DEFARGS_PRESENT          = 0x01,
    DA_REWRITES                 = 0x02,
    DA_NULL                     = 0x00
};

typedef struct {
    PSTK_CTL    with_generic;
    PSTK_CTL    without_generic;
    PSTK_CTL    bindings;
} type_bind_info;

// masking

// For TypeDefModifierRemoveOnly
#define MASK_TD_REMOVE_ONLY \
    ( 1 << TYP_MODIFIER ) | \
    ( 1 << TYP_TYPEDEF )

// For TypeDefModifierRemove
#define MASK_TD_REMOVE      \
    ( 1 << TYP_MODIFIER ) | \
    ( 1 << TYP_TYPEDEF )  | \
    ( 1 << TYP_ENUM )     | \
    ( 1 << TYP_BOOL )     | \
    ( 1 << TYP_CHAR )

#define TypeIdMasked( typ, mask ) ( (mask) & ( 1 << ( (typ)->id ) ) )

#define TypeStrip( type, mask ) if( type != NULL ) \
    for( ; TypeIdMasked( type, mask ); type = type->of );
#define TypeStripTdMod( type ) TypeStrip( type, MASK_TD_REMOVE_ONLY )
#define TypeStripTdModEnumChar( type ) TypeStrip( type, MASK_TD_REMOVE )



// extra reporting (debug only)

ExtraRptCtr( types_defined );
ExtraRptCtr( types_alloced );
ExtraRptCtr( ctr_dups );
ExtraRptCtr( ctr_dup_succ );
ExtraRptCtr( ctr_dup_succ_probes );
ExtraRptCtr( ctr_dup_fail );
ExtraRptCtr( ctr_dup_fail_probes );
ExtraRptCtr( ctr_dup_fns );
ExtraRptCtr( ctr_dup_fns_big );
ExtraRptCtr( ctr_lookup );
ExtraRptCtr( ctr_cg_dups );
ExtraRptCtr( ctr_cg_dups_fail );
ExtraRptTable( ctr_type_ids, TYP_MAX, 1 );
ExtraRptTable( ctr_fn_args, ARGS_MAX+1+1, 1 );


static DECL_INFO *makeDeclInfo( PTREE id )
{
    DECL_INFO *dinfo;

    dinfo = CarveAlloc( carveDECL_INFO );
    dinfo->next = NULL;
    dinfo->id = id;
    dinfo->scope = NULL;
    dinfo->friend_scope = NULL;
    dinfo->list = NULL;
    dinfo->parms = NULL;
    dinfo->sym = NULL;
    dinfo->generic_sym = NULL;
    dinfo->proto_sym = NULL;
    dinfo->name = NULL;
    dinfo->type = NULL;
    dinfo->defarg_expr = NULL;
    dinfo->body = NULL;
    dinfo->mem_init = NULL;
    dinfo->defarg_rewrite = NULL;
    dinfo->init_locn.src_file = NULL;
    dinfo->sym_used = FALSE;
    dinfo->friend_fn = FALSE;
    dinfo->fn_defn = FALSE;
    dinfo->template_member = FALSE;
    dinfo->has_dspec = FALSE;
    dinfo->has_defarg = FALSE;
    dinfo->explicit_parms = FALSE;
    return( dinfo );
}


TYPE GetBasicType( type_id id )
/*****************************/
/* return a pointer to one of the predefined "standard" types */
{
    DbgAssert( basicTypes[ id ] != NULL );
    return( basicTypes[ id ] );
}

static CLASSINFO *newINFO( void )
{
    CLASSINFO *info;

    info = CarveAlloc( carveCLASSINFO );
    info->bases = NULL;
    info->friends = NULL;
    info->name = NULL;
    info->cdopt_cache = NULL;
    info->size = 0;
    info->vsize = 0;
    info->refno = NULL_CGREFNO;
    info->dbg_no_vbases = 0;
    info->class_mod = NULL;
    info->last_vfn = 0;
    info->last_vbase = 0;
    info->vf_offset = 0;
    info->vb_offset = 0;
    info->index = 0;
    info->max_align = TARGET_CHAR;

    info->has_def_opeq = FALSE;
    info->has_ctor = FALSE;
    info->has_def_ctor = FALSE;
    info->has_dtor = FALSE;
    info->has_pure = FALSE;
    info->has_vfptr = FALSE;
    info->has_vbptr = FALSE;
    info->has_data = FALSE;
    info->has_vfn = FALSE;
    info->has_vcdtor = FALSE;
    info->needs_ctor = FALSE;
    info->needs_dtor = FALSE;
    info->needs_vdtor = FALSE;
    info->needs_assign = FALSE;
    info->defined = FALSE;
    info->unnamed = FALSE;
    info->corrupted = FALSE;
    info->abstract = FALSE;
    info->abstract_OK = FALSE;
    info->const_copy = FALSE;
    info->const_assign = FALSE;
    info->const_ref = FALSE;
    info->anonymous = FALSE;

    info->ctor_defined = FALSE;
    info->copy_defined = FALSE;
    info->dtor_defined = FALSE;
    info->assign_defined = FALSE;
    info->ctor_gen = FALSE;
    info->copy_gen = FALSE;
    info->dtor_gen = FALSE;
    info->assign_gen = FALSE;
    info->ctor_user_code = FALSE;
    info->copy_user_code = FALSE;
    info->dtor_user_code = FALSE;
    info->assign_user_code = FALSE;
    info->ctor_user_code_checked = FALSE;
    info->copy_user_code_checked = FALSE;
    info->dtor_user_code_checked = FALSE;
    info->assign_user_code_checked = FALSE;
    info->opened = FALSE;
    info->zero_array = FALSE;
    info->passed_ref = FALSE;

    info->free = FALSE;
    info->lattice = FALSE;
    info->vftable_done = FALSE;
    info->vbtable_done = FALSE;
    info->has_udc = FALSE;
    info->common = FALSE;
    info->has_comp_info = FALSE;
    info->has_mutable = FALSE;
    info->empty = FALSE;
    info->has_fn = FALSE;

    return( info );
}

TYPE MakeType( type_id id )
/*************************/
{
    TYPE new_type;

    new_type = CarveAlloc( carveTYPE );
    ExtraRptIncrementCtr( types_alloced );
    ExtraRptIncrementCtr( types_defined );
    new_type->next = NULL;
    new_type->of = NULL;
    new_type->u.i.init1 = NULL;
    new_type->u.i.init2 = NULL;
    new_type->id = id;
    new_type->dbg.handle = typeHashCtr++;
    new_type->dbg.pch_handle = 0;
    new_type->flag = TF1_NULL;
    new_type->dbgflag = TF2_HASH;
    return( new_type );
}

TYPE MakeClassType( void )
/************************/
{
    TYPE new_type;

    new_type = MakeType( TYP_CLASS );
    new_type->u.c.info = newINFO();
    return( new_type );
}

static void typeFree( TYPE type )
{
    DbgVerify( ! ( type->dbgflag & TF2_DBG_IN_PCH ), "type was in a pre-compiled header!" );
    switch( type->id ) {
    case TYP_CLASS:
        DbgAssert( type->u.c.info->cdopt_cache == NULL );
        CarveFree( carveCLASSINFO, type->u.c.info );
        break;
    }
    CarveFree( carveTYPE, type );
    ExtraRptDecrementCtr( types_defined );
}

TYPE MakeArrayType( unsigned long size )
/**************************************/
{
    TYPE    new_type;

    new_type = MakeType( TYP_ARRAY );
    new_type->u.a.array_size = size;
    return( new_type );
}

TYPE MakeArrayOf( unsigned long size, TYPE base )
/***********************************************/
{
    TYPE array_type;

    array_type = MakeArrayType( size );
    return( MakeTypeOf( array_type, base ) );
}

// An expandable type will have the array size change and so cannot
// be placed within any type-compression lists.
//
TYPE MakeExpandableType( type_id base_id )
/****************************************/
{
    TYPE expands;

    expands = MakeArrayType( 1 );
    expands->of = GetBasicType( base_id );
    return expands;
}

TYPE MakeModifiedType( TYPE type, type_flag flag )
/************************************************/
{
    if( flag != TF1_NULL ) {
        type = MakeTypeOf( MakeFlagModifier( flag ), type );
    }
    return( type );
}

TYPE MakeCommonCodeData( TYPE type )
/**********************************/
{
    return( MakeModifiedType( type, TF1_COMMON ) );
}

TYPE MakeForceInMemory( TYPE type )
/*********************************/
{
    return( MakeModifiedType( type, TF1_IN_MEM ) );
}

TYPE MakeInternalType( target_size_t size )
/*****************************************/
{
    return( MakeArrayOf( size, GetBasicType( TYP_UCHAR ) ) );
}

static TYPE makeFullModifier( type_flag flag, void *base, AUX_INFO *pragma )
{
    TYPE new_type;

    new_type = MakeType( TYP_MODIFIER );
    new_type->flag = flag;
    new_type->u.m.base = base;
    new_type->u.m.pragma = pragma;
    return( new_type );
}

static TYPE dupModifier( TYPE type )
{
    return( makeFullModifier( type->flag, type->u.m.base, type->u.m.pragma ) );
}

TYPE MakeFlagModifier( type_flag flag )
/*************************************/
{
    return( makeFullModifier( flag, NULL, NULL ) );
}

TYPE MakeVolatileModifier( void )
/*******************************/
{
    return( MakeFlagModifier( TF1_VOLATILE ) );
}

TYPE MakeConstModifier( void )
/****************************/
{
    return( MakeFlagModifier( TF1_CONST ) );
}

TYPE MakeConstTypeOf( TYPE type )
/*******************************/
{
    return( MakeTypeOf( MakeConstModifier(), type ) );
}

TYPE MakeVolatileTypeOf( TYPE type )

⌨️ 快捷键说明

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