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 + -
显示快捷键?