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