anallval.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,061 行 · 第 1/3 页
C
1,061 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include "plusplus.h"
#include "memmgr.h"
#include "cgfront.h"
#include "fold.h"
#include "errdefns.h"
#include "objmodel.h"
#include "stats.h"
#include "brinfo.h"
#define isUDF( node ) ( node->cgop == CO_NAME_CONVERT )
static TYPE lvalueErrMsg( // GENERATE NOT-LVALUE ERROR MESSAGE
PTREE expr_chk, // - expression, to be checked
PTREE expr_err, // - expression, for error
unsigned msg_normal, // - msg, when normal
unsigned msg_cast ) // - msg, when cast
{
if( NodeIsBinaryOp( expr_chk, CO_CONVERT ) ) {
expr_chk = PTreeOpLeft( expr_chk );
if( expr_chk->cgop == CO_USER_CAST ) {
PTreeErrorExpr( expr_err, msg_cast );
} else {
PTreeErrorExpr( expr_err, msg_normal );
}
} else {
PTreeErrorExpr( expr_err, msg_normal );
}
return NULL;
}
TYPE LvalueErr( // NOT-LVALUE ERROR (NODE)
PTREE expr_chk, // - expression, to be checked
PTREE expr ) // - expression
{
return lvalueErrMsg( expr_chk
, expr
, ERR_MUST_BE_LVALUE
, ERR_MUST_BE_LVALUE_CAST );
}
TYPE LvalueErrLeft( // NOT-LVALUE ERROR (LEFT NODE)
PTREE expr_chk, // - expression, to be checked
PTREE expr ) // - expression
{
return lvalueErrMsg( expr_chk
, expr
, ERR_LEFT_MUST_BE_LVALUE
, ERR_LEFT_MUST_BE_LVALUE_CAST );
}
static boolean requiresThis( // TEST IF SYMBOL REQUIRES A THIS
SYMBOL sym ) // - symbol
{
boolean retn; // - TRUE ==> requires "this"
SCOPE func_class_scope; // - scope for function
if( SymIsClassMember( sym ) ) {
if( SymIsStaticMember( sym ) || SymIsEnumeration( sym ) ) {
retn = FALSE;
} else if( NULL == TypeThisExists() ) {
retn = TRUE;
} else {
func_class_scope = ScopeFunctionScopeInProgress()->enclosing;
if( ( func_class_scope->id == SCOPE_CLASS )
&&( ScopeDerived( func_class_scope, SymScope( sym ) ) ) ) {
retn = FALSE;
} else {
retn = TRUE;
}
}
} else {
retn = FALSE;
}
return retn;
}
boolean AnalyseSymbolAccess( // ANALYSE ACCESS TO SYMBOL
PTREE expr, // - expression for errors
PTREE symbol, // - symbol being accessed
PTREE this_expr, // - expression for "this"
SYMBOL_DIAG *diag ) // - diagnosis to be used
{
boolean retn; // - return: TRUE ==> access ok
SEARCH_RESULT *result; // - search result
TOKEN_LOCN err_locn; // - location for errors
PTreeExtractLocn( expr, &err_locn );
result = symbol->u.symcg.result;
#ifdef OPT_BR
if( CompFlags.optbr_f
|| CompFlags.optbr_m
|| CompFlags.optbr_t
|| CompFlags.optbr_v ) {
BrinfReferenceSymbol( &err_locn, symbol->u.symcg.symbol );
}
#endif
ScopeResultErrLocn( result, &err_locn );
SymSetNvReferenced( symbol->u.symcg.symbol );
if( ScopeCheckSymbol( result, symbol->u.symcg.symbol ) ) {
PTreeErrorNode( expr );
retn = FALSE;
} else if( this_expr == NULL ) {
if( result->simple ) {
retn = TRUE;
} else if( result->no_this ) {
retn = TRUE;
} else if( requiresThis( symbol->u.symcg.symbol ) ) {
PTreeErrorExpr( expr, diag->msg_no_this );
retn = FALSE;
} else {
retn = TRUE;
}
} else {
retn = SymIsClassMember( symbol->u.symcg.symbol );
}
return retn;
}
static SYMBOL_DIAG diagMemb = // diagnosis for member
{ ERR_INVALID_NONSTATIC_ACCESS// - no "this"
, ERR_EXTRA_THIS_FOR_DATA // - extra "this" for data element
, ERR_ENCLOSING_THIS_DATA // - accessing enclosing class member
};
boolean AnalyseThisDataItem( // ANALYSE "THIS" DATA ITEM IN PARSE TREE
PTREE *a_expr ) // - addr[ expression ]
{
boolean retn; // - return: TRUE ==> ok
PTREE expr; // - expression
SEARCH_RESULT *result; // - search result for node
PTREE *r_right; // - ref[ node for symbol to be adjusted ]
PTREE right; // - node for symbol to be adjusted
unsigned offset; // - offset for field
TYPE type; // - field type
type_flag flags; // - cv flags, when bit field
expr = *a_expr;
r_right = PTreeRefRight( expr );
right = *r_right;
if( AnalyseSymbolAccess( expr
, right
, expr->u.subtree[0]
, &diagMemb ) ) {
type = NodeType( expr->u.subtree[0] );
type = TypedefModifierRemove( type )->of;
type = TypeMergeForMember( type, expr->type );
result = right->u.symcg.result;
right->u.symcg.result = NULL;
if( expr->u.subtree[0]->flags & PTF_MEMORY_EXACT ) {
offset = result->exact_delta + result->offset;
right = NodeReplace( right, NodeOffset( offset ) );
*r_right = right;
} else if( result->non_virtual ) {
offset = result->delta + result->offset;
right = NodeReplace( right, NodeOffset( offset ) );
*r_right = right;
} else {
expr = NodePruneRight( expr );
expr = NodePruneTop( expr );
expr->flags |= PTF_PTR_NONZERO;
NodeConvertToBasePtr( &expr, type, result, TRUE );
expr->flags |= PTF_LVALUE | PTF_LV_CHECKED;
expr = NodeBinary( CO_DOT, expr, NodeOffset( result->offset ) );
}
expr->type = type;
expr->flags |= PTF_LVALUE;
ScopeFreeResult( result );
type = TypeModFlags( type, &flags );
if( type->id == TYP_BITFIELD ) {
expr = NodeUnaryCopy( CO_BITFLD_CONVERT, expr );
expr->type = MakeModifiedType( type->of, flags & TF1_CV_MASK );
expr->flags |= PTF_LVALUE;
}
expr = NodeSetMemoryExact( expr );
expr = NodeFetchReference( expr );
expr->flags |= PTF_LV_CHECKED;
*a_expr = expr;
retn = TRUE;
} else {
retn = FALSE;
}
return retn;
}
static PTREE reduceToRight( // REDUCE EXPRESSION TO RIGHT EXPR
PTREE *a_node ) // - addr( expression )
{
PTREE node; // - expression
node = NodePruneLeftTop( *a_node );
*a_node = node;
return node;
}
static PTREE thisPointsNode( // MAKE this->node
PTREE node ) // - original node
{
TYPE type; // - node type
PTREE left; // - this node to left
left = NodeThisCopyLocation( node );
if( left == NULL ) {
PTreeErrorExpr( node, ERR_INVALID_NONSTATIC_ACCESS );
} else {
type = node->type;
node = NodeBinary( CO_ARROW, left, node );
node->type = type;
node->flags |= PTF_LVALUE;
node = PTreeCopySrcLocation( node, left );
}
return node;
}
static boolean checkConversionLookup( // CHECK RESULT OF CONVERSION LOOKUP
SEARCH_RESULT *result, // - result of lookup
PTREE conv, // - node for conversion routine
PTREE expr ) // - node being analysed
{
boolean retn; // - TRUE ==> ok
if( ( result == NULL ) || ( result->sym == NULL ) ) {
PTreeErrorExpr( conv, ERR_CONVERSION_NOT_DEFINED );
PTreeErrorNode( expr );
retn = FALSE;
} else {
ExtraRptSymUsage( result->sym );
NodeSymbolCallee( conv, result->sym, result );
retn = TRUE;
}
return retn;
}
static boolean checkIdLookup( // CHECK RESULT OF ID LOOKUP
SEARCH_RESULT *result, // - result of lookup
SCOPE scope, // - scope for lookup
PTREE id, // - node for id
PTREE expr ) // - node being analysed
{
boolean retn; // - TRUE ==> ok
SYMBOL sym; // - a symbol lookup up
unsigned msg; // - undeclared sym error message
char *name; // - id name
if( result == NULL ) {
ScopeInsertErrorSym( scope, id );
name = id->u.id.name;
msg = ERR_UNDECLARED_SYM;
if( ScopeType( scope, SCOPE_CLASS ) ) {
if( NodeIsBinaryOp( expr, CO_DOT ) ) {
msg = ERR_UNDECLARED_MEMBER;
} else if( NodeIsBinaryOp( expr, CO_ARROW ) ) {
msg = ERR_UNDECLARED_MEMBER;
}
}
if( msg == ERR_UNDECLARED_SYM ) {
PTreeErrorExprName( id, msg, name );
} else {
PTreeErrorExprNameType( id, msg, name, ScopeClass( scope ) );
}
PTreeErrorNode( expr );
retn = FALSE;
} else {
sym = result->sym_name->name_syms;
if( sym == NULL ) {
PTreeErrorExpr( id, ERR_ILLEGAL_TYPE_USE );
ScopeFreeResult( result );
PTreeErrorNode( expr );
retn = FALSE;
} else if( SymIsAnError( sym ) ) {
ScopeFreeResult( result );
PTreeErrorNode( expr );
retn = FALSE;
} else if( NULL != FunctionDeclarationType( sym->sym_type ) ) {
ExtraRptSymUsage( sym );
NodeSymbolNoRef( id, sym, result );
id->flags |= PTF_LV_CHECKED;
retn = TRUE;
} else {
ExtraRptSymUsage( sym );
NodeSymbol( id, sym, result );
id->flags |= PTF_LV_CHECKED;
retn = TRUE;
}
}
return retn;
}
static boolean analyseFunction( // ANALYSE FUNCTION NODE
PTREE expr, // - original expression
PTREE func ) // - function node
{
boolean retn; // - TRUE ==> function ok
if( ScopeImmediateCheck( func->u.symcg.result ) ) {
PTreeErrorNode( expr );
retn = FALSE;
} else {
expr->flags |= PTF_LVALUE;
retn = TRUE;
}
return retn;
}
static void checkVolatileVar( // SET SIDE EFFECT IF VOLATILE VARIABLE
PTREE expr ) // - expression for variable
{
type_flag flags; // - flags for expression
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?