⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cexpr2.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            break;
        case T___OW_IMAGINARY_UNIT:
            {
            FLOATVAL    *flt;
            tree = LeafNode( OPR_PUSHFLOAT );
            tree->op.const_type = TYPE_DIMAGINARY;
            flt = CMemAlloc( sizeof(FLOATVAL) + 3 );
            flt->string[0] = '+';
            strcpy( &flt->string[1], "1.0" );
            flt->len = 3 + 1;
            flt->type = TYPE_DIMAGINARY;
            flt->next = NULL;
            tree->op.float_value = flt;
            tree->op.opr = OPR_PUSHFLOAT;
            tree->expr_type = GetType( tree->op.const_type );
            }
            NextToken();
            break;
        default:
            if( CompFlags.pre_processing  &&    /* 07-mar-92 */
                CurToken >= FIRST_KEYWORD  &&  CurToken < T_MACRO_PARM ) {
                tree = ExprId();
            } else {
                CErr1( ERR_MISSING_OPERAND );
                tree = ErrorNode( NULL );
            }
        }
        break;
    }
    --Level;
    return( tree );
}


local TREEPTR ExprId()
{
    TREEPTR     tree;
    int         value;
    int         count;

    if( CompFlags.pre_processing ) {
        if( strcmp( Buffer, "defined" ) == 0 ) {
            CompFlags.pre_processing = 2;       /* don't want macro expanded */
            NextToken();
            if( CurToken == T_LEFT_PAREN ) {
                NextToken();
                value = IsMacroDefined();
                NextToken();
                MustRecog( T_RIGHT_PAREN );
                CompFlags.pre_processing = 1;
            } else {
                value = IsMacroDefined();
                CompFlags.pre_processing = 1;
                NextToken();
            }
        } else {
//          if( SizeOfCount == 0 ) {                    /* 17-jul-94 */
//              CWarn( WARN_UNDECLARED_PP_SYM, ERR_UNDECLARED_PP_SYM, Buffer);
//          }
            NextToken();
            if( CurToken == T_LEFT_PAREN ) {    /* 26-may-89 */
                count = 0;
                for(;;) {               /* flush to ')' or end of line */
                    NextToken();
                    if( CurToken == T_NULL ) break;
                    if( CurToken == T_LEFT_PAREN )      ++count;
                    if( CurToken == T_RIGHT_PAREN ) {
                        if( count == 0 ) {
                            NextToken();
                            break;
                        }
                        --count;
                    }
                }
            }
            value = 0;
        }
        tree = IntLeaf( value );
    } else {
        tree = SymLeaf();
    }
    return( tree );
}


local int IsMacroDefined()
{
    MEPTR       mentry;

    if( CurToken != T_ID ) {
        ExpectIdentifier();
    } else {
        mentry = MacroLookup( Buffer );
        if( mentry != NULL ) {
            mentry->macro_flags |= MACRO_REFERENCED;    /* 04-apr-94 */
            return( 1 );
        }
    }
    return( 0 );
}
#if 0
local int LValueArray( TREEPTR tree )
{
    TYPEPTR     typ;

    if( tree->op.opr == OPR_PUSHSTRING ) {
        return( 1 );
    } else if( IsLValue( tree ) ) {
        return( 1 );
    } else {
        typ = tree->expr_type;
        while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
        if( typ->decl_type == TYPE_POINTER ) {
            return( 1 );
        }
    }
    return( 0 );
}
#endif
local TREEPTR GenIndex( TREEPTR tree, TREEPTR index_expr )
{
    TYPEPTR         typ;
    type_modifiers  tree_flags;

//  if( ! LValueArray( tree ) ) {
//      CErr1( ERR_CANT_TAKE_ADDR_OF_RVALUE );
//      FreeExprTree( index_expr );
//      return( ErrorNode( tree ) );
//  }
    index_expr = RValue( index_expr );
    if( DataTypeOf( TypeOf(index_expr)->decl_type ) > TYPE_ULONG64 ) {
        CErr1( ERR_EXPR_MUST_BE_INTEGRAL );
        FreeExprTree( tree );
        return( ErrorNode( index_expr ) );
    }
    typ = tree->expr_type;
    while( typ->decl_type == TYPE_TYPEDEF ) {
        typ = typ->object;
    }
    if( typ->decl_type == TYPE_ARRAY ){
        tree_flags = tree->op.flags;  // get modifiers of array obj
    }else if( typ->decl_type == TYPE_POINTER ){
       // We will indirect so get modifiers of indirected obj
        tree_flags = OpFlags( typ->u.p.decl_flags );
    }else{
        CErr2p(ERR_FATAL_ERROR, "Bad array index tree" );
    }
    typ = typ->object;
    while( typ->decl_type == TYPE_TYPEDEF ) {
        typ = typ->object;
    }
    // Some crappy little optimization that probably does nothing
    if( index_expr->op.opr == OPR_PUSHINT  &&
        tree->expr_type->decl_type == TYPE_ARRAY ) {
        index_expr->op.long_value *= SizeOfArg( typ );
        tree = ExprNode( tree, OPR_DOT, index_expr );
        #if _CPU == 8086
            if( index_expr->op.long_value > 0x7FFF ) {
                index_expr->op.const_type = TYPE_LONG;
                index_expr->expr_type = GetType( TYPE_LONG );
            }
        #endif
    } else {
        #if _CPU == 8086
            if( DataTypeOf( TypeOf(index_expr)->decl_type ) == TYPE_UINT ) {
                if(( tree_flags & OPFLAG_HUGEPTR ) ||
                   ((TargetSwitches & (BIG_DATA|CHEAP_POINTER))==BIG_DATA &&
                    (tree_flags & (OPFLAG_NEARPTR | OPFLAG_FARPTR))==0)) {
                    index_expr = CnvOp( index_expr, GetType( TYPE_LONG ), 0 );
                }
            }
        #endif
        tree = ExprNode( tree, OPR_INDEX, index_expr );
    }
    tree->expr_type = typ;
    tree->op.result_type = typ;
    tree->op.flags = tree_flags;
    return( tree );
}

local TREEPTR ArrayIndex( TREEPTR tree, TREEPTR index_expr )
{
    tree = GenIndex( tree, index_expr );
    return( tree );
}


local TREEPTR IndexOp( TREEPTR tree, TREEPTR index_expr )
{
    TYPEPTR     typ;

    if( tree->op.opr == OPR_ERROR )  return( tree );
    typ = tree->expr_type;
    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    if( typ->decl_type == TYPE_ARRAY ) {
        tree = ArrayIndex( tree, index_expr );
    } else if( typ->decl_type == TYPE_POINTER ) {
        tree = GenIndex( RValue(tree), index_expr );
    } else {                    /* try index[array] */
        typ = index_expr->expr_type;
        while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
        if( typ->decl_type == TYPE_ARRAY ) {
            tree = ArrayIndex( index_expr, tree );
        } else if( typ->decl_type == TYPE_POINTER ) {
            tree = GenIndex( RValue(index_expr), tree );
        } else {
            CErr1( ERR_EXPR_MUST_BE_ARRAY );
            FreeExprTree( index_expr );
            tree = ErrorNode( tree );
        }
    }
    MustRecog( T_RIGHT_BRACKET );
    return( tree );
}

local void AddCallNode( TREEPTR tree ){
// if a function call has no proto type wait till end
// to check it out
    call_list  *new;

    if( tree->left != NULL ){ // could be errors
        new = CMemAlloc( sizeof( call_list ) );
        new->next = NULL;
        new->callnode = tree;
        new->source_fno = SrcFno;
        new->srclinenum = SrcLineNum;
        *LastCallLnk = new;
        LastCallLnk =  &new->next;
    }
}

void ChkCallNode( TREEPTR tree ){
    call_list **lnk;
    call_list *curr;
    lnk = FirstCallLnk;
    while( (curr = *lnk) != NULL ){
        if( curr->callnode == tree ){
            curr->callnode = NULL;
            break;
        }
        lnk = &curr->next;
    }
}

static int ParmNum( void ){
// get current parm num
    int parm_count,n;

    parm_count = 1;
    n = Level;
    while( Token[ n ] != T_LEFT_PAREN ) {
        --n;
        ++parm_count;
    }
    return( parm_count );
}

local TREEPTR GenNextParm( TREEPTR tree, TYPEPTR **plistptr )
{
    TYPEPTR     *plist;
    TYPEPTR     typ;
    TYPEPTR     typ2;
    TYPEPTR     parm_typ;

    tree = RValue( tree );
    if( tree->op.opr == OPR_ERROR )     return( tree );
    typ = SkipTypeFluff( tree->expr_type );
    plist = *plistptr;
    if( plist != NULL ) {
        if( *plist == NULL || (*plist)->decl_type == TYPE_VOID ){  // To many parm trees
#if _CPU == 386
        /* can allow wrong number of parms with -3s option; 06-dec-91 */
            if( ! CompFlags.register_conventions ) {
                CWarn1( WARN_PARM_COUNT_MISMATCH, ERR_PARM_COUNT_WARNING );
            }else{
                CErr1( ERR_PARM_COUNT_MISMATCH );           /* 18-feb-90 */
            }
#else
            CErr1( ERR_PARM_COUNT_MISMATCH );           /* 18-feb-90 */
#endif
            *plist = GetType( TYPE_DOT_DOT_DOT ); //shut up message
            plist = NULL;
        } else if( (*plist)->decl_type == TYPE_DOT_DOT_DOT ) {
            plist = NULL;
        }
    }
    if( plist != NULL ) {  //do conversion from tree to parm type
        parm_typ = *plist;
        ParmAsgnCheck( parm_typ, tree, ParmNum() );
        if( parm_typ != NULL ) {
            parm_typ = SkipTypeFluff( parm_typ );
            if( parm_typ != typ ) {
                if( parm_typ->decl_type == TYPE_POINTER  && /* 08-jun-89 */
                    typ->decl_type != TYPE_POINTER ) {
                    if( tree->op.opr == OPR_PUSHINT ) {
                        if( tree->op.long_value == 0 ) { /* 22-sep-89 */
                            typ = parm_typ;
                            tree = ParmAss( tree, typ );
                        }
                    }
                } else if( typ->decl_type != TYPE_POINTER ||/* 26-may-89 */
                    parm_typ->decl_type == TYPE_POINTER ) { /* 04-jun-89 */
                    typ = parm_typ;
                    switch( typ->decl_type ) {      /* 25-may-91 */
                    case TYPE_STRUCT:
                    case TYPE_UNION:
                        break;
                    default:
                        tree = ParmAss( tree, typ );
                        break;
                    }
                }
            }
            ++*plistptr;
        }
    } else {
        if( typ->decl_type == TYPE_FLOAT ) { // default conversions
            typ = GetType( TYPE_DOUBLE );
            tree = ParmAss( tree, typ );
        } else if( typ->decl_type == TYPE_POINTER ) {   /* 17-nov-88 */
            typ2 = typ->object;
            while( typ2->decl_type == TYPE_TYPEDEF )  typ2 = typ2->object;
            if( typ2->decl_type != TYPE_FUNCTION ) {
                if( typ->u.p.decl_flags & FLAG_NEAR ) {
                    if( DataPtrSize == TARGET_FAR_POINTER ) {
                        typ = PtrNode( typ2, FLAG_NONE, SEG_DATA );
                        tree = ParmAss( tree, typ );
                    }
                }
            }
        }
    }
    if( typ->decl_type == TYPE_POINTER ) typ = typ->object;
    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    if( typ->decl_type == TYPE_DOUBLE ||
        typ->decl_type == TYPE_FLOAT ) {
        CompFlags.float_used = 1;
    }
    return( tree );
}


local int IntrinsicMathFunc( SYM_NAMEPTR sym_name, int i, int n, SYMPTR sym )
{
    auto char func_name[6];

    if( far_strcmp( sym_name, MathFuncs[i].name, n ) == 0 )  return( 1 );
    if( sym->flags & SYM_INTRINSIC ) {
        strcpy( func_name, &MathFuncs[i].name[2] );/* copy name without __ */
        strlwr( func_name );
        if( far_strcmp( sym_name, func_name, n ) == 0 )  return( 1 );
    }
    return( 0 );        /* indicate not a math intrinsic function */
}

#if _MACHINE == _ALPHA  || _MACHINE == _PPC
local TREEPTR GenVaStartNode( TREEPTR last_parm )
{
    // there should be 3 parms __builtin_va_start( list, parm_name, stdarg )
    // - first parm should be name of va_list
    // - second parm should be name of the parameter before the ...
    // - last_parm should be an integer 0 or 1 (0=>varargs, 1=>stdarg)

    SYMPTR      sym;
    SYM_HANDLE  parm_list;
    int         offset;
    TREEPTR     parmsym;
    TREEPTR     tree;

    tree = NULL;
    if( Level >= 2 &&
        Token[Level] != T_LEFT_PAREN &&
        Token[Level-1] != T_LEFT_PAREN &&
        Token[Level-2] == T_LEFT_PAREN ) {
        offset = 0;
        if( last_parm->op.opr == OPR_PUSHINT &&
            last_parm->op.long_value == 0 ) {           // varargs.h
            offset = -8;
        }
        parmsym = ValueStack[Level];            // get name of parameter
        parm_list = 0;
        if( parmsym->op.opr == OPR_PUSHSYM ) {
            parm_list = CurFunc->u.func.parms;
            while( parm_list != 0 ) {
                sym = SymGetPtr( parm_list );
                offset += (SizeOfArg( sym->sym_type ) + 7) & -8;
                if( parm_list == parmsym->op.sym_handle ) break;
                parm_list = sym->handle;
            }
        }
        if( offset == 0 || parm_list == 0 ) {
            // error: name not found in parm list
            sym = SymGetPtr( parmsym->op.sym_handle );
            CErr2p( ERR_SYM_NOT_IN_PARM_LIST,
                        SymName( sym, parmsym->op.sym_handle ) );
        }
        FreeExprNode( parmsym );
        tree = ValueStack[ Level - 1 ];
        if( tree->op.opr == OPR_PUSHSYM ) {
           

⌨️ 快捷键说明

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