anallval.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,061 行 · 第 1/3 页

C
1,061
字号
    TypeModFlags( expr->type, &flags );
    if( flags & TF1_VOLATILE ) {
        expr->flags |= PTF_SIDE_EFF;
    }
}


static boolean analyseBareSymbol( // ANALYSE AN BARE SYMBOL
    PTREE *a_expr )             // - addr( symbol entry )
{
    PTREE expr;                 // - symbol entry
    PTREE alias;                // - alias expr
    boolean retn;               // - return: TRUE ==> all ok
    SYMBOL sym;                 // - the symbol

    expr = *a_expr;
    sym = expr->u.symcg.symbol;
    if( SymIsAnError( sym ) ) {
        PTreeErrorNode( expr );
        retn = FALSE;
    } else if( sym->id == SC_ADDRESS_ALIAS ) {
        alias = NodeSymbol( NULL, sym->u.alias, expr->u.symcg.result );
        alias = PTreeCopySrcLocation( alias, expr );
        if( PointerType( sym->sym_type ) != NULL ) {
            alias = NodeConvert( sym->sym_type, alias );
        }
        PTreeFree( expr );
        *a_expr = alias;
        retn = TRUE;
    } else if( NULL != FunctionDeclarationType( sym->sym_type ) ) {
        if( MainProcedure( sym ) ) {
            PTreeErrorExpr( expr, ERR_REFERENCED_MAIN );
            retn = FALSE;
        } else {
            retn = analyseFunction( expr, expr );
        }
    } else {
        sym = SymDeAlias( sym );
        expr->u.symcg.symbol = sym;
        retn = AnalyseSymbolAccess( expr, expr, NULL, &diagMemb );
        NodeFreeSearchResult( expr );
        if( retn ) {
            if( SymIsEnumeration( sym ) ) {
                sym = expr->u.symcg.symbol;
                PTreeFree( expr );
                expr = NodeFromConstSym( sym );
                expr->type = sym->sym_type;
            } else {
                expr = NodeSetMemoryExact( expr );
                expr = NodeFetchReference( expr );
                checkVolatileVar( expr );
            }
            *a_expr = expr;
            retn = TRUE;
        }
    }
    return retn;
}

static boolean massageStaticEnumAccess( // x.static, x.enum adjustments
    PTREE *a_expr )             // - addr( member expr )
{
#ifdef OLD_STATIC_MEMBER_ACCESS
    boolean retn;

    reduceToRight( a_expr );
    retn = analyseBareSymbol( a_expr );
#else
    PTREE expr;
    PTREE lhs;
    PTREE rhs;
    boolean retn;

    expr = *a_expr;
    DbgAssert( NodeIsBinaryOp( expr, CO_ARROW ) || NodeIsBinaryOp( expr, CO_DOT ) );
    lhs = expr->u.subtree[0];
    expr->u.subtree[0] = NULL;
    rhs = expr->u.subtree[1];
    expr->u.subtree[1] = NULL;
    PTreeFree( expr );
    retn = analyseBareSymbol( &rhs );
    *a_expr = NodeCommaIfSideEffect( lhs, rhs );
#endif
    return retn;
}


static boolean analyseMemberExpr( // ANALYSE A MEMBER EXPRESION
    PTREE *a_expr )             // - addr( member expression )
{
    PTREE expr;                 // - symbol entry
    boolean retn;               // - return value
    SYMBOL sym;                 // - the symbol

    expr = *a_expr;
    if( expr->op == PT_ERROR ) {
        retn = FALSE;
    } else {
        DbgAssert( expr->u.subtree[1]->op == PT_SYMBOL );
        sym = expr->u.subtree[1]->u.symcg.symbol;
        expr->type = sym->sym_type;
        if( NULL != FunctionDeclarationType( sym->sym_type ) ) {
            retn = analyseFunction( expr, expr->u.subtree[1] );
        } else if( SymIsStaticDataMember( sym ) || SymIsEnumeration( sym ) ) {
            retn = massageStaticEnumAccess( a_expr );
        } else {
            retn = AnalyseThisDataItem( a_expr );
            if( retn ) {
                checkVolatileVar( *a_expr );
                retn = TRUE;
            }
        }
    }
    return retn;
}


static boolean analyseSymbol(   // ANALYSE AN UNDECORATED SYMBOL
    PTREE *a_expr )             // - addr( symbol entry )
{
    PTREE expr;                 // - symbol entry
    boolean retn;               // - return value
    SYMBOL sym;                 // - the symbol

    expr = *a_expr;
    sym = expr->u.symcg.symbol;
    if( SymIsThisDataMember( sym ) ) {
        if( expr->u.symcg.result->use_this ) {
            expr = thisPointsNode( expr );
            *a_expr = expr;
            if( expr->op == PT_ERROR ) {
                retn = FALSE;
            } else {
                retn = analyseMemberExpr( a_expr );
            }
        } else {
            PTreeErrorExpr( expr, ERR_INVALID_NONSTATIC_ACCESS );
            retn = FALSE;
        }
    } else {
        retn = analyseBareSymbol( a_expr );
    }
    return retn;
}


static boolean analyseMember(   // ANALYSE A MEMBER NODE
    PTREE *a_expr,              // - addr( expression for member )
    SCOPE start,                // - scope to start lookup
    SCOPE disamb )              // - scope to disambiguate
{
    PTREE member;               // - node for member
    PTREE expr;                 // - expression
    SEARCH_RESULT *result;      // - result of search
    boolean retn;               // - TRUE ==> ok

    expr = *a_expr;
    member = PTreeOpRight( expr );
    if( isUDF( member ) ) {
        result = ScopeFindScopedMemberConversion( start
                                                , disamb
                                                , member->type
                                                , TF1_NULL );
        retn = checkConversionLookup( result, member, expr );
    } else {
        result = ScopeFindScopedMember( start, disamb, member->u.id.name );
        retn = checkIdLookup( result, start, member, expr );
    }
    if( retn ) {
        retn = analyseMemberExpr( a_expr );
    }
    return retn;
}


static boolean simpleTypeDtor(  // TEST IF DTOR OF A SIMPLE TYPE
    TYPE type,                  // - type to be DTOR'd
    PTREE expr )                // - "->" or "." expression
{
    boolean retn;               // - return: TRUE ==> is DTOR of simple type
    PTREE right;                // - right  operand

    type = type;                // may have to check some day
    right = PTreeOpRight( expr );
    if( ( right->op == PT_ID )
      &&( right->cgop == CO_NAME_DTOR ) ) {
        retn = TRUE;
    } else {
        retn = FALSE;
    }
    return retn;
}


static boolean analyseDtor(     // ANALYSE A DTOR CALL
    PTREE *a_expr,              // - addr[ DTOR expression, before lookup ]
    SCOPE scope,                // - scope of object
    SCOPE disamb )              // - NULL or disambiguating scope
{
    PTREE expr;                 // - DTOR expression, before lookup
    PTREE dtor;                 // - possible DTOR symbol
    boolean retn;               // - return: TRUE ==> everything ok
    SEARCH_RESULT *result;      // - result of search

    expr = *a_expr;
    dtor = expr->u.subtree[1];
    if( scope != TypeScope( dtor->type ) ) {
        PTreeErrorExpr( dtor, ERR_DTOR_NOT_SAME );
        PTreeErrorNode( expr );
        retn = FALSE;
    } else {
        dtor = expr->u.subtree[1];
        if( disamb == NULL ) {
            result = DtorFindResult( dtor->type );
            retn = checkIdLookup( result, scope, dtor, expr );
            if( retn ) {
                retn = analyseMemberExpr( a_expr );
            }
        } else {
            if( disamb != scope ) {
                PTreeErrorExpr( dtor, ERR_DTOR_BAD_QUAL );
                PTreeErrorNode( dtor );
                retn = FALSE;
            } else {
                DtorFind( dtor->type );
                result = ScopeContainsMember( scope
                                            , CppDestructorName() );
                retn = checkIdLookup( result, scope, dtor, expr );
                if( retn ) {
                    retn = analyseMemberExpr( a_expr );
                }
            }
        }
    }
    return retn;
}


static boolean analyseMembRight(// ANALYSE MEMBER ON RIGHT
    PTREE *a_expr,              // - addr( expression for member )
    TYPE type )                 // - type for class on left
{
    boolean retn;               // - return: TRUE ==> is ok
    PTREE expr;                 // - operation
    PTREE right;                // - right operand
    SCOPE scope;                // - scope for class
    SCOPE disamb;               // - disambiguating scope

    if( type == NULL ) {
        retn = FALSE;
    } else {
        scope = TypeScope( type );
        expr = *a_expr;
        if( scope == NULL ) {
            expr->type = TypeVoidFunOfVoid();
            retn = TRUE;                // assumes only DTOR will get thru
        } else {
            right = expr->u.subtree[1];
            if( right->op == PT_ID ) {
                disamb = NULL;
                if( right->cgop == CO_NAME_DTOR ) {
                    retn = analyseDtor( a_expr, scope, disamb );
                } else {
                    retn = analyseMember( a_expr, scope, disamb );
                }
            } else if( NodeIsBinaryOp( right, CO_COLON_COLON ) ) {
                if( right->u.subtree[0] == NULL ) { // - already lexical error
                    PTreeErrorNode( expr );
                    retn = FALSE;
                } else {
                    disamb = TypeScope( right->u.subtree[0]->type );
                    right = reduceToRight( &expr->u.subtree[1] );
                    right->flags |= PTF_COLON_QUALED;
                    if( right->cgop == CO_NAME_DTOR ) {
                        retn = analyseDtor( a_expr, scope, disamb );
                    } else {
                        retn = analyseMember( a_expr, scope, disamb );
                    }
                }
            } else if( right->op == PT_SYMBOL ) {
                // this will be the form from datainit.c
                retn = analyseMemberExpr( a_expr );
#ifndef NDEBUG
            } else {
                CFatal( "corrupted member tree" );
#endif
            }
        }
    }
    return retn;
}

static TYPE diagMember( PTREE left, PTREE expr, unsigned msg )
{
    TYPE left_type;

    left_type = NodeType( left );
    PTreeErrorExpr( left, msg );
    InfMsgPtr( INF_OPERAND_TYPE, left_type );
    PTreeErrorNode( expr );
    return NULL;
}


static TYPE analyseClPtrLeft(   // ANALYSE A CLASS POINTER ON LEFT
    PTREE *a_expr )             // - addr( expression )
{
    PTREE expr;                 // - operation
    PTREE left;                 // - left node
    TYPE type;                  // - node type

    expr = *a_expr;
    left = NodeRvalueLeft( expr );
    type = TypedefModifierRemove( left->type );
    if( ( type->id != TYP_POINTER ) || ( TF1_REFERENCE & type->flag ) ) {
        type = diagMember( left, expr, ERR_MUST_BE_PTR_TO_STRUCT_OR_UNION );
    } else {
        type = type->of;
        if( NULL == StructType( type ) ) {
            if( ! simpleTypeDtor( type, expr ) ) {
                type = diagMember( left, expr, ERR_MUST_BE_PTR_TO_STRUCT_OR_UNION );
            }
        } else {
            if( ! TypeDefined( type ) ) {
                PTreeErrorExpr( left, ERR_UNDEFED_CLASS_PTR );
                InfClassDecl( type );
                PTreeErrorNode( expr );
                type = NULL;
            } else if( ! NodeDerefPtr( &expr->u.subtree[0] ) ) {
                PTreeErrorNode( expr );
                type = NULL;
            }
        }
    }
    return type;
}


static TYPE analyseClassLeft(   // ANALYSE A CLASS ON LEFT
    PTREE *a_expr )             // - addr( expression )
{
    PTREE expr;                 // - operation
    PTREE left;                 // - left node
    TYPE type;                  // - type for class

    expr = *a_expr;
    left = PTreeOpLeft( expr );
    if( left->flags & PTF_LVALUE ) {
        type = left->type;
        if( ( NULL == ClassTypeForType( type ) )
          &&( ! simpleTypeDtor( type, expr ) ) ) {
            type = diagMember( left, expr, ERR_MUST_BE_STRUCT_OR_UNION );
        } else if( ! TypeDefined( type ) ) {
            PTreeErrorExpr( left, ERR_UNDEFINED_CLASS_OBJECT );

⌨️ 快捷键说明

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