cdecl1.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 573 行 · 第 1/2 页
C
573 行
if( info.stg != SC_NULL && info.stg != SC_REGISTER ) {
CErr1( ERR_INVALID_STG_CLASS_FOR_PARM );
info.stg = SC_NULL;
}
state = DECL_STATE_NONE;
typ = info.typ;
if( typ == NULL ) {
state |= DECL_STATE_NOTYPE;
typ = TypeDefault();
}
if( info.stg == SC_NULL )
info.stg = SC_AUTO;
for( ;; ) {
if( CurToken == T_SEMI_COLON ) {
Chk_Struct_Union_Enum( typ );
} else {
sym.name = NULL; /* 04-oct-91 */
Declarator( &sym, info.mod, typ, state );
if( sym.name == NULL || sym.name[0] == '\0' ) {
InvDecl();
} else {
for( parm = ParmList; parm; ) {
if( parm->sym.name != NULL ) { /* 03-may-93 */
if( strcmp( parm->sym.name, sym.name ) == 0 ) {
break;
}
}
parm = parm->next_parm;
}
if( parm == NULL ) {
CErr2p( ERR_SYM_NOT_IN_PARM_LIST, sym.name );
} else if( parm->sym.sym_type != NULL ) {
CErr2p( ERR_PARM_ALREADY_DECLARED, sym.name );
} else {
ArgPromotion( &sym );
parm->sym.sym_type = sym.sym_type;
parm->sym.stg_class = info.stg;
}
}
CMemFree( sym.name );
}
if( CurToken == T_SEMI_COLON ) {
NextToken();
break;
}
if( CurToken == T_LEFT_BRACE ) {
CErr1( ERR_MISSING_SEMICOLON );
break;
}
if( CurToken == T_EOF )
return;
MustRecog( T_COMMA );
}
}
ReverseParms();
if( CurFunc->sym_type->u.fn.parms == NULL ) {
CurFunc->flags |= SYM_OLD_STYLE_FUNC; /* 13-sep-89 */
AddParms();
} else {
ChkParms();
}
ParmList = NULL;
if( VarParm( CurFunc ) ) {
CurFunc->flags &= ~ SYM_OK_TO_RECURSE; /* 25-sep-91 */
}
}
local void ReverseParms( void ) /* reverse order of parms */
{
PARMPTR prev_parm, parm, next_parm;
if( ParmsToBeReversed( CurFunc->attrib, NULL ) ) {
prev_parm = NULL;
parm = ParmList;
while( parm != NULL ) {
next_parm = parm->next_parm;
parm->next_parm = prev_parm;
prev_parm = parm;
parm = next_parm;
}
ParmList = prev_parm;
}
}
local void ChkProtoType( void )
{
TYPEPTR ret1;
TYPEPTR ret2;
TYPEPTR typ1;
TYPEPTR typ2;
typ1 = CurFunc->sym_type;
SKIP_TYPEDEFS( typ1 );
ret1 = typ1->object;
typ2 = PrevProtoType;
SKIP_TYPEDEFS( typ2 );
ret2 = typ2->object;
typ1->object = NULL;
typ2->object = NULL;
VerifyType( CurFunc->sym_type, PrevProtoType, CurFunc );
typ1->object = ret1;
typ2->object = ret2;
}
local void AddParms( void )
{
PARMPTR parm;
PARMPTR prev_parm;
SYM_HANDLE sym_handle;
SYM_HANDLE prev_sym_handle = 0;
SYM_HANDLE new_sym_handle;
TYPEPTR typ = NULL;
int parm_count;
int hash;
struct parm_list *parmlist;
SYM_ENTRY new_sym;
CurFunc->u.func.locals = 0;
CurFunc->u.func.parms = 0;
parm = ParmList;
parmlist = NULL;
parm_count = 0;
prev_parm = NULL;
while( parm != NULL ) {
new_sym_handle = 0;
parm->sym.flags |= SYM_DEFINED | SYM_ASSIGNED;
parm->sym.is_parm = TRUE;
hash = parm->sym.info.hash_value;
if( parm->sym.name[0] == '\0' ) {
/* no name ==> ... */
parm->sym.sym_type = GetType( TYPE_DOT_DOT_DOT );
parm->sym.stg_class = SC_AUTO;
} else if( parm->sym.sym_type == NULL ) {
parm->sym.sym_type = TypeDefault();
parm->sym.stg_class = SC_AUTO;
} else {
/*
go through ParmList again, looking for FLOAT parms
change the name to ".P" and duplicate the symbol with type
float and generate an assignment statement.
*/
typ = parm->sym.sym_type;
SKIP_TYPEDEFS( typ );
switch( typ->decl_type ) {
case TYPE_CHAR:
case TYPE_UCHAR:
case TYPE_SHORT:
if( CompFlags.strict_ANSI ) {
parm->sym.sym_type = GetType( TYPE_INT );
}
break;
case TYPE_USHORT:
if( CompFlags.strict_ANSI ) {
#if TARGET_SHORT == TARGET_INT
parm->sym.sym_type = GetType( TYPE_UINT );
#else
parm->sym.sym_type = GetType( TYPE_INT );
#endif
}
break;
case TYPE_FLOAT:
memcpy( &new_sym, &parm->sym, sizeof(SYM_ENTRY) );
new_sym.handle = CurFunc->u.func.locals;
new_sym_handle = SymAdd( hash, &new_sym );
CurFunc->u.func.locals = new_sym_handle;
SymReplace( &new_sym, new_sym_handle );
parm->sym.name = ".P";
parm->sym.flags |= SYM_REFERENCED; /* 24-nov-89 */
parm->sym.sym_type = GetType( TYPE_DOUBLE );
break;
default:
break;
}
}
sym_handle = SymAdd( hash, &parm->sym );
if( new_sym_handle != 0 ) {
TREEPTR tree;
tree = ExprNode( VarLeaf( &new_sym, new_sym_handle ),
OPR_EQUALS, RValue( VarLeaf(&parm->sym, sym_handle) ) );
tree->op.result_type = typ;
tree->expr_type = typ;
AddStmt( tree );
}
if( prev_parm == NULL ) {
CurFunc->u.func.parms = sym_handle;
} else {
prev_parm->sym.handle = sym_handle;
SymReplace( &prev_parm->sym, prev_sym_handle );
CMemFree( prev_parm );
}
prev_parm = parm;
prev_sym_handle = sym_handle;
++parm_count;
parmlist = NewParm( parm->sym.sym_type, parmlist );
parm = parm->next_parm;
}
if( prev_parm != NULL ) {
prev_parm->sym.handle = 0;
SymReplace( &prev_parm->sym, prev_sym_handle );
CMemFree( prev_parm );
}
typ = CurFunc->sym_type;
// TODO not following my scheme
CurFunc->sym_type = FuncNode( typ->object, FLAG_NONE,
MakeParmList( parmlist, parm_count,
ParmsToBeReversed( CurFunc->attrib, NULL ) ) );
if( PrevProtoType != NULL ) { /* 12-may-91 */
ChkProtoType();
}
}
local void ChkParms( void )
{
PARMPTR parm;
PARMPTR prev_parm;
SYM_HANDLE sym_handle;
SYM_HANDLE prev_sym_handle = 0;
TYPEPTR typ;
CurFunc->u.func.locals = 0;
CurFunc->u.func.parms = 0;
parm = ParmList;
prev_parm = NULL;
typ = *(CurFunc->sym_type->u.fn.parms);
SKIP_TYPEDEFS( typ );
if( typ->decl_type != TYPE_VOID ) {
while( parm != NULL ) {
if( parm->sym.name == NULL ) { /* 03-may-93 */
parm->sym.name = ".J";
parm->sym.flags |= SYM_REFERENCED;
}
if( parm->sym.name[0] == '\0' ) {
parm->sym.name = ".I";
InvDecl();
}
if( parm->sym.sym_type == NULL ) {
parm->sym.sym_type = TypeDefault();
}
/* make sure name not already defined in this SymLevel */
sym_handle = SymAdd( parm->sym.info.hash_value, &parm->sym );
if( prev_parm == NULL ) {
CurFunc->u.func.parms = sym_handle;
} else {
prev_parm->sym.handle = sym_handle;
SymReplace( &prev_parm->sym, prev_sym_handle );
CMemFree( prev_parm );
}
prev_parm = parm;
prev_sym_handle = sym_handle;
parm->sym.flags |= SYM_DEFINED | SYM_ASSIGNED;
parm->sym.is_parm = TRUE;
parm = parm->next_parm;
}
if( prev_parm != NULL ) {
#if _CPU == 370 /* 24-oct-91 */
{
SYM_ENTRY var_parm;
if( VarParm( CurFunc ) ) {
typ = ArrayNode( GetType( TYPE_CHAR ) );
typ->u.array->dimension = 160;
sym_handle = GetNewSym( &var_parm, 'V', typ, SC_AUTO );
SymReplace( &var_parm, sym_handle );
prev_parm->sym.handle = sym_handle;
}
}
#endif
SymReplace( &prev_parm->sym, prev_sym_handle );
CMemFree( prev_parm );
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?