📄 cdecl2.c
字号:
parms = NULL;
if( CurToken != T_RIGHT_PAREN ) {
parm_list = ParmList;
ParmList = NULL;
parms = FuncProtoType();
if( parms == NULL && ParmList != NULL ) {
if( CurToken == T_SEMI_COLON || CurToken == T_COMMA ) {
/* int f16(i,j); */
CErr1( ERR_ID_LIST_SHOULD_BE_EMPTY );
}
}
if( parm_list != NULL ) {
FreeParmList();
ParmList = parm_list;
}
} else {
NextToken(); /* skip over ')' */
}
if( typ != NULL ) { /* 09-apr-90 */
TYPEPTR typ2;
typ2 = typ; /* 08-dec-93 */
while( typ2->decl_type == TYPE_TYPEDEF ) typ2 = typ2->object;
if( typ2->decl_type == TYPE_ARRAY ) {
CErr1( ERR_FUNCTION_CANT_RETURN_AN_ARRAY );
} else if( typ2->decl_type == TYPE_FUNCTION ) {
CErr1( ERR_FUNCTION_CANT_RETURN_A_FUNCTION );
}
}
typ = FuncNode( typ, mod, parms );
return( typ );
}
static TYPEPTR DeclPart2( TYPEPTR typ, type_modifiers mod )
{
if( CurToken == T_LEFT_PAREN ) {
NextToken();
typ = DeclPart3( typ, mod );
}
for(;;) {
if( CurToken == T_LEFT_BRACKET ) {
typ = ArrayDecl( typ );
}
if( CurToken != T_LEFT_PAREN ) break;
NextToken();
typ = DeclPart3( typ, mod );
}
return( typ );
}
local void CheckUniqueName( PARMPTR parm, char *name ) /* 13-apr-89 */
{
if( name != NULL ) { /* 29-oct-91 */
if( *name != '\0' ) {
for( ; parm ; parm = parm->next_parm ) {
if( parm->sym.name != NULL ) { /* 16-oct-92 */
if( strcmp( parm->sym.name, name ) == 0 ) {
CErr2p( ERR_SYM_ALREADY_DEFINED, name );
parm->sym.flags |= SYM_REFERENCED;
}
}
}
}
}
}
struct parm_list *NewParm( TYPEPTR typ, struct parm_list *prev_parm )
{
struct parm_list *parm;
parm = (struct parm_list *)CMemAlloc( sizeof( struct parm_list ) );
parm->parm_type = typ;
parm->next_parm = prev_parm;
return( parm );
}
void AdjParmType( SYMPTR sym )
{
TYPEPTR typ;
typ = sym->sym_type;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
if( typ->decl_type == TYPE_FUNCTION ) {
sym->sym_type = PtrNode( sym->sym_type, sym->attrib, SEG_CODE );
sym->attrib = FLAG_NONE;
} else if( typ->decl_type == TYPE_ARRAY ) {
sym->sym_type = PtrNode( typ->object,
FLAG_WAS_ARRAY | sym->attrib,
SEG_DATA );
sym->attrib = FLAG_NONE;
}
}
local TYPEPTR *GetProtoType( decl_info *first )
{
PARMPTR parm;
PARMPTR prev_parm = NULL;
PARMPTR parm_namelist;
int parm_count;
struct parm_list *parmlist;
decl_state state;
declspec_class declspec;
stg_classes stg_class;
type_modifiers mod;
TYPEPTR typ;
decl_info info;
parm_count = 0;
parmlist = NULL;
parm_namelist = NULL;
info = *first;
for(;;) {
SYMPTR sym; // parm sym
stg_class = info.stg;
declspec = info.decl;
typ = info.typ;
mod = info.mod;
if( stg_class != SC_NULL && stg_class != SC_REGISTER ) {
CErr1( ERR_INVALID_STG_CLASS_FOR_PARM_PROTO );
}
state = DECL_STATE_ISPARM;
if( typ == NULL ) {
state |= DECL_STATE_NOTYPE;
if( stg_class == SC_NULL ) { /* 30-nov-94 */
CErr1( ERR_TYPE_REQUIRED_IN_PARM_LIST );
}
typ = TypeDefault();
}
parm = (PARMPTR) CMemAlloc( sizeof( PARM_ENTRY ) );
parm->next_parm = NULL;
sym = &parm->sym;
memset( sym, 0, sizeof( SYM_ENTRY ) ); /* 02-apr-91 */
sym->name = "";
Declarator( sym, mod, typ, state );
typ = sym->sym_type;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
if( typ->decl_type == TYPE_VOID ) {
char buffer[20];
char *name;
if( sym->name[0] == '\0' ) {
sprintf( buffer, "Parm %d", parm_count );
name = buffer;
}else{
name = sym->name;
}
CErr2p( ERR_VAR_CANT_BE_VOID, name );
sym->sym_type = TypeDefault();
}
if( stg_class == SC_NULL ) {
stg_class = SCSpecifier(); /* 17-mar-91 */
if( stg_class == SC_NULL ) stg_class = SC_AUTO;
}
sym->stg_class = stg_class;
AdjParmType( sym );
parmlist = NewParm( sym->sym_type, parmlist );
if( parm_count == 0 ) {
parm_namelist = parm;
} else {
CheckUniqueName( parm_namelist, sym->name );
prev_parm->next_parm = parm;
}
if( (Toggles & TOGGLE_UNREFERENCED) == 0 ) {
sym->flags |= SYM_REFERENCED;
}
++parm_count;
if( CurToken == T_RIGHT_PAREN ) break;
if( CurToken == T_EOF || CurToken == T_LEFT_BRACE ) break;
MustRecog( T_COMMA );
if( CurToken == T_DOT_DOT_DOT ) {
typ = GetType( TYPE_DOT_DOT_DOT );
parmlist = NewParm( typ, parmlist );
NextToken();
break;
}
prev_parm = parm;
FullDeclSpecifier( &info );
}
ParmList = parm_namelist;
/* if void is specified as a parm, it is the only parm allowed */
return( MakeParmList( parmlist, parm_count, 0 ) );
}
TYPEPTR *MakeParmList( struct parm_list *parm, int parm_count, int reversed )
{
TYPEPTR *type_list;
struct parm_list *next_parm, *prev_parm;
TYPEPTR typ;
int index;
type_list = NULL;
if( parm != NULL ) {
if( ! reversed ) {
prev_parm = NULL;
for(;;) {
next_parm = parm->next_parm;
parm->next_parm = prev_parm;
if( next_parm == NULL ) break;
prev_parm = parm;
parm = next_parm;
}
}
parm_count = 0;
next_parm = parm;
while( next_parm != NULL ) {
++parm_count;
next_parm = next_parm->next_parm;
}
/* try to find an existing parm list that matches, 29-dec-88 */
index = parm_count;
if( index > MAX_PARM_LIST_HASH_SIZE ) {
index = MAX_PARM_LIST_HASH_SIZE;
}
for( typ = FuncTypeHead[ index ]; typ; typ = typ->next_type ) {
type_list = typ->u.parms;
next_parm = parm;
for(;;) {
if( next_parm == NULL ) {
if( *type_list != NULL ) break;
while( parm != NULL ) {
next_parm = parm->next_parm;
CMemFree( parm );
parm = next_parm;
}
return( typ->u.parms );
}
if( next_parm->parm_type != *type_list ) break;
next_parm = next_parm->next_parm;
++type_list;
}
}
type_list = (TYPEPTR *)CPermAlloc( (parm_count+1)*sizeof(TYPEPTR));
if( type_list != NULL ) {
type_list[ parm_count ] = NULL;
parm_count = 0;
while( parm != NULL ) {
type_list[ parm_count ] = parm->parm_type;
next_parm = parm->next_parm;
CMemFree( parm );
parm = next_parm;
++parm_count;
}
}
}
return( type_list );
}
local int VoidType( TYPEPTR typ ) /* 03-oct-91 */
{
if( typ != NULL ) {
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
if( typ->decl_type == TYPE_VOID ) return( 1 );
}
return( 0 );
}
local TYPEPTR *FuncProtoType()
{
TYPEPTR *type_list;
TAGPTR old_taghead;
decl_info info;
if( !CompFlags.extensions_enabled ) ++SymLevel; /* 03-may-89 */
old_taghead = TagHead;
FullDeclSpecifier( &info );
if( info.stg == SC_NULL && info.typ == NULL ) {
GetFuncParmList();
if( CurToken == T_RIGHT_PAREN ) {
NextToken();
} else {
Expecting( ")" ); /* 24-mar-91 */
}
type_list = NULL;
} else { /* function prototype present */
if( VoidType( info.typ ) && /*27-dec-88*/
info.stg== SC_NULL && CurToken == T_RIGHT_PAREN ) {
type_list = VoidParmList;
} else {
type_list = GetProtoType( &info );
}
if( CurToken == T_RIGHT_PAREN ) {
NextToken();
} else {
Expecting( ")" ); /* 24-mar-91 */
}
if( CurToken != T_LEFT_BRACE ) { /* 18-jan-89 */
if( SymLevel > 1 || /* 03-dec-90 */
! CompFlags.extensions_enabled ) { /* 25-jul-91 */
/* get rid of any new tags regardless of SymLevel; 23-jul-90 */
TagHead = old_taghead; /* get rid of new tags from proto */
FreeEnums(); /* 03-may-89 */
}
}
}
if( !CompFlags.extensions_enabled ) --SymLevel; /* 03-may-89 */
return( type_list );
}
local void GetFuncParmList( void )
{
PARMPTR parm = NULL;
PARMPTR newparm;
PARMPTR parm_namelist;
parm_namelist = NULL;
while( CurToken == T_ID ) { /* scan off func parm list */
if( parm_namelist == NULL ) {
parm = (PARMPTR) CMemAlloc( sizeof( PARM_ENTRY ) );
SymCreate( &parm->sym, Buffer );
parm_namelist = parm;
} else {
newparm = (PARMPTR) CMemAlloc( sizeof( PARM_ENTRY ) );
SymCreate( &newparm->sym, Buffer );
CheckUniqueName( parm_namelist, Buffer );
parm->next_parm = newparm;
parm = newparm;
}
parm->sym.info.hash_value = HashValue;
if( (Toggles & TOGGLE_UNREFERENCED) == 0 ) {
parm->sym.flags |= SYM_REFERENCED;
}
NextToken();
if( CurToken == T_RIGHT_PAREN ) break;
if( CurToken == T_EOF ) break;
if( CurToken != T_COMMA ) { /* 04-jan-89 */
MustRecog( T_COMMA ); /* forces error msg */
for(;;) { /* skip until ')' to avoid cascading errors */
if( CurToken == T_RIGHT_PAREN ) break;
if( CurToken == T_EOF ) break;
NextToken();
}
break;
}
MustRecog( T_COMMA );
if( CurToken == T_DOT_DOT_DOT ) {
parm->next_parm = (PARMPTR) CMemAlloc( sizeof( PARM_ENTRY ) );
parm = parm->next_parm;
SymCreate( &parm->sym, "" );
/* set flags so we don't give funny error messages */
parm->sym.flags |= SYM_TEMP | SYM_ASSIGNED | SYM_REFERENCED;
NextToken();
break;
}
}
ParmList = parm_namelist;
}
local void FreeParmList( void )
{
PARMPTR parm;
for( ; (parm = ParmList); ) {
ParmList = parm->next_parm;
CMemFree( parm->sym.name );
CMemFree( parm );
}
}
#if _CPU == 370
local bool IsIntComp( TYPEPTR ret1 )
/*
* what's target compatible between default int as ret type
* and a later declaration
*/
{
bool ret;
while( ret1->decl_type == TYPE_TYPEDEF ) ret1 = ret1->object;
switch( ret1->decl_type ) {
case TYPE_CHAR:
case TYPE_UCHAR:
case TYPE_SHORT:
case TYPE_USHORT:
case TYPE_INT:
case TYPE_LONG:
ret = TRUE;
break;
default:
ret = FALSE;
}
return( ret );
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -