示例#1
0
static void ChkParms( void )
{
    PARMPTR             parm;
    PARMPTR             prev_parm;
    SYM_HANDLE          sym_handle;
    SYM_HANDLE          prev_sym_handle;
    TYPEPTR             typ;

    CurFunc->u.func.locals = SYM_NULL;
    CurFunc->u.func.parms = SYM_NULL;
    typ = *(CurFunc->sym_type->u.fn.parms);
    SKIP_TYPEDEFS( typ );
    if( typ->decl_type != TYPE_VOID ) {
        prev_sym_handle = SYM_NULL;
        prev_parm = NULL;
        for( parm = ParmList; parm != NULL; parm = parm->next_parm ) {
            if( parm->sym.name == NULL ) {
                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, &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.attribs.is_parm = true;
        }
        if( prev_parm != NULL ) {
#if _CPU == 370
            {
                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 );
        }
    }
}
示例#2
0
TYPEPTR EnumDecl( int flags )
{
    TYPEPTR     typ;
    TAGPTR      tag;

    flags = flags;
    NextToken();
    if( CurToken == T_ID ) {
        /* could be: (1) "enum" <id> ";"
                     (2) "enum" <id> <variable_name> ";"
                     (3) "enum" <id> "{" <enum_const_decl> ... "}"
        */
        tag = TagLookup();
        NextToken();
        if( CurToken != T_LEFT_BRACE ) {
            typ = tag->sym_type;
            if( typ == NULL ) {
                CErr1( ERR_INCOMPLETE_ENUM_DECL );
                typ = TypeDefault();
            } else {
                if( typ->decl_type != TYPE_ENUM ) {         /* 18-jan-89 */
                    CErr2p( ERR_DUPLICATE_TAG, tag->name );
                }
                typ->u.tag = tag;
            }
            return( typ );
        }
        tag = VfyNewTag( tag, TYPE_ENUM );
    } else {
        tag = NullTag();
    }
    typ = TypeNode( TYPE_ENUM, GetType( TYPE_INT ) );
    typ->u.tag = tag;
    tag->sym_type = typ;
    tag->size = TARGET_INT;
    tag->u.enum_list = NULL;
    if( CurToken == T_LEFT_BRACE ) {
        const_val       val;
        enum enum_rng   index;
        enum enum_rng   const_index;
        enum enum_rng   start_index;
        enum enum_rng   step;
        enum enum_rng   error;
        uint64          n;
        uint64          Inc;
        bool            minus;
        bool            has_sign;
        ENUMPTR         *prev_lnk;
        ENUMPTR         esym;
        source_loc      error_loc;
        char            buff[50];

        if( CompFlags.make_enums_an_int ) {
            start_index = ENUM_INT;
        } else {
            start_index = ENUM_S8;
        }
        const_index = ENUM_UNDEF;
        NextToken();
        if( CurToken == T_RIGHT_BRACE ) {
            CErr1( ERR_EMPTY_ENUM_LIST );
        }
        U32ToU64( 1, &Inc );
        U64Clear( n );
        minus = FALSE;
        has_sign = FALSE;
        step = 1;
        prev_lnk = &esym;
        esym = NULL;
        while( CurToken == T_ID ) {
            esym = EnumLkAdd( tag );
            *prev_lnk = esym;
            prev_lnk = &esym->thread;
            error_loc = TokenLoc;
            NextToken();
            if( CurToken == T_EQUAL ) {
                NextToken();
                error_loc = TokenLoc;
                ConstExprAndType( &val );
                switch( val.type ){
                case TYPE_ULONG:
                case TYPE_UINT:
                case TYPE_ULONG64:
                    minus = FALSE;
                    break;
                default:
                    if( val.value.u.sign.v ) {
                        minus = TRUE;
                        step = 2;
                    } else {
                        minus = FALSE;
                    }
                    break;
                }
                n = val.value;
            } else if( has_sign ) {
                if( n.u.sign.v ) {
                    minus = TRUE;
                } else {
                    minus = FALSE;
                }
            }
            for( index = start_index; index < ENUM_SIZE; index += step ) {
                if( minus ) {
                    if( I64Cmp( &n, &( RangeTable[ index ][LOW] ) ) >= 0 ) break;
                } else {
                    if( U64Cmp( &n, &( RangeTable[ index ][HIGH]) ) <= 0 ) break;
                }
            }
            error = ENUM_UNDEF;
            if( !CompFlags.extensions_enabled && ( index > ENUM_INT )) {
                error = ENUM_INT;
            }
            if( index >= ENUM_SIZE ) {
                // overflow signed maximum range
                if( error == ENUM_UNDEF ) {
                    error = const_index;
                }
            } else if(( const_index == ENUM_SIZE - 1 ) && minus ) {
                // overflow unsigned maximum range by any negative signed value
                if( error == ENUM_UNDEF )
                    error = const_index;
                step = 1;
            } else {
                if( !has_sign && minus) {
                    has_sign = TRUE;
                    if( index < const_index ) {
                        // round up to signed
                        index = ( const_index + 1 ) & ~1;
                    }
                }
                if( index > const_index ) {
                    const_index = index;
                    typ->object = GetType( ItypeTable[const_index].decl_type );
                    tag->size   = ItypeTable[const_index].size;
                }
            }
            if( error != ENUM_UNDEF ) {
                SetErrLoc( &error_loc );
                get_msg_range( buff, error );
                CErr2p( ERR_ENUM_CONSTANT_OUT_OF_RANGE, buff );
                InitErrLoc();
            }
            esym->value = n;
            EnumTable[ esym->hash ] = esym;             /* 08-nov-94 */
            if( CurToken == T_RIGHT_BRACE )
                break;
            U64Add( &n, &Inc, &n );
            MustRecog( T_COMMA );
            if( !CompFlags.extensions_enabled
              && !CompFlags.c99_extensions
              && ( CurToken == T_RIGHT_BRACE )) {
                ExpectIdentifier();         /* 13-may-91 */
            }
        }
        MustRecog( T_RIGHT_BRACE );
    }
    return( typ );
}
示例#3
0
static void AddParms( void )
{
    PARMPTR             parm;
    PARMPTR             prev_parm;
    SYM_HANDLE          sym_handle;
    SYM_HANDLE          prev_sym_handle;
    SYM_HANDLE          new_sym_handle;
    TYPEPTR             typ = NULL;
    int                 parm_count;
    id_hash_idx         h;
    parm_list           *parmlist;
    SYM_ENTRY           new_sym;

    CurFunc->u.func.locals = SYM_NULL;
    CurFunc->u.func.parms = SYM_NULL;
    parmlist = NULL;
    prev_sym_handle = SYM_NULL;
    parm_count = 0;
    prev_parm = NULL;
    for( parm = ParmList; parm != NULL; parm = parm->next_parm ) {
        new_sym_handle = SYM_NULL;
        parm->sym.flags |= SYM_DEFINED | SYM_ASSIGNED;
        parm->sym.attribs.is_parm = true;
        h = parm->sym.info.hash;
        if( parm->sym.name[0] == '\0' ) {
            /* no name ==> ... */
            parm->sym.sym_type = GetType( TYPE_DOT_DOT_DOT );
            parm->sym.attribs.stg_class = SC_AUTO;
        } else if( parm->sym.sym_type == NULL ) {
            parm->sym.sym_type = TypeDefault();
            parm->sym.attribs.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( h, &new_sym );
                CurFunc->u.func.locals = new_sym_handle;
                SymReplace( &new_sym, new_sym_handle );
                parm->sym.name = ".P";
                parm->sym.flags |= SYM_REFERENCED;
                parm->sym.sym_type = GetType( TYPE_DOUBLE );
                break;

            default:
                break;
            }
        }
        sym_handle = SymAdd( h, &parm->sym );
        if( new_sym_handle != SYM_NULL ) {
            TREEPTR         tree;

            tree = ExprNode( VarLeaf( &new_sym, new_sym_handle ),
                             OPR_EQUALS, RValue( VarLeaf( &parm->sym, sym_handle ) ) );
            tree->op.u2.result_type = typ;
            tree->u.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 );
    }
    if( prev_parm != NULL ) {
        prev_parm->sym.handle = SYM_NULL;
        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, ParmsToBeReversed( CurFunc->mods, NULL ) ) );

    if( PrevProtoType != NULL ) {
        ChkProtoType();
    }
}
示例#4
0
static void ParmDeclList( void )     /* process old style function definitions */
{
    TYPEPTR             typ;
    PARMPTR             parm;
    decl_state          state;
    SYM_ENTRY           sym;
    decl_info           info;
    size_t              len;

    while( CurToken != T_LEFT_BRACE ) {
        FullDeclSpecifier( &info );
        if( info.stg == SC_NONE && info.typ == NULL ) {
            if( CurToken == T_ID ) {
                CErr2p( ERR_MISSING_DATA_TYPE, Buffer );
            }
        }
        if( info.stg != SC_NONE && info.stg != SC_REGISTER ) {
            CErr1( ERR_INVALID_STG_CLASS_FOR_PARM );
            info.stg = SC_NONE;
        }
        state = DECL_STATE_NONE;
        typ = info.typ;
        if( typ == NULL ) {
            state |= DECL_STATE_NOTYPE;
            typ = TypeDefault();
        }
        if( info.stg == SC_NONE )
            info.stg = SC_AUTO;

        for( ;; ) {
            if( CurToken == T_SEMI_COLON ) {
                Chk_Struct_Union_Enum( typ );
            } else {
                sym.name = NULL;
                Declarator( &sym, info.mod, typ, state );
                if( sym.name == NULL || sym.name[0] == '\0' ) {
                    InvDecl();
                } else {
                    len = strlen( sym.name ) + 1;
                    for( parm = ParmList; parm != NULL; parm = parm->next_parm ) {
                        if( parm->sym.name != NULL ) {
                            if( memcmp( parm->sym.name, sym.name, len ) == 0 ) {
                                break;
                            }
                        }
                    }
                    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.attribs.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;
        AddParms();
    } else {
        ChkParms();
    }
    ParmList = NULL;
    if( VarParm( CurFunc ) ) {
        CurFunc->flags &= ~ SYM_OK_TO_RECURSE;
    }
}