analnode.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,101 行 · 第 1/5 页
C
2,101 行
{
if( flags & PTF_LVALUE ) {
if( NULL == TypeReference( type ) ) {
type = MakeReferenceTo( type );
}
}
expr = NodeConvert( type, expr );
expr = NodeSetType( expr, type, flags );
return expr;
}
PTREE NodeSetBooleanType( // SET NODE TO TYPE OF A REL-OP EXPR
PTREE expr ) // - expression
{
expr->flags |= PTF_BOOLEAN;
expr->type = GetBasicType( TYP_BOOL );
return expr;
}
PTREE NodeCompareToZero( // MAKE A COMPARE-TO-ZERO NODE, IF REQ'D
PTREE expr )
{
PTREE zero; // - constant node (contains zero)
PTREE operand; // - operand to be compared
TYPE type; // - expression type, unmodified
if( expr->flags & PTF_BOOLEAN ) {
return expr;
}
if( PTreeOpFlags( expr ) & PTO_BOOLEAN ) {
return expr;
}
type = TypeReferenced( expr->type );
type = TypedefModifierRemoveOnly( type );
if( type->id == TYP_VOID ) {
PTreeErrorExpr( expr, ERR_EXPR_IS_VOID );
} else {
if( ( NULL == StructType( type ) )
&&( NULL == MemberPtrType( type ) ) ) {
expr = NodeRvalue( expr );
if( ! ArithType( type ) ) {
// may be &fn or array decay to a pointer
type = expr->type;
}
} else {
type = GetBasicType( TYP_SINT );
}
operand = expr;
zero = NodeIntegralConstant( 0, type );
expr = NodeBinary( CO_NE, operand, zero );
expr = PTreeCopySrcLocation( expr, operand );
expr = NodeSetBooleanType( expr );
expr = ConvertBoolean( expr );
}
return expr;
}
static CNV_DIAG diagConvertToBool = // DIAGNOSIS FOR CONVERT-TO-BOOL NODE
{ ERR_IMPLICIT_CAST_ILLEGAL // - impossible
, ERR_CALL_WATCOM // - ambiguous
, ERR_CALL_WATCOM
, ERR_CALL_WATCOM // - protected violation
, ERR_CALL_WATCOM // - private violation
};
PTREE NodeConvertToBool( // MAKE A CONVERT-TO-BOOL NODE, IF REQ'D
PTREE expr )
{
PTREE zero; // - constant node (contains zero)
PTREE operand; // - operand to be compared
TYPE type; // - expression type, unmodified
if( expr->flags & PTF_BOOLEAN ) {
return expr;
}
if( PTreeOpFlags( expr ) & PTO_BOOLEAN ) {
return expr;
}
type = TypeReferenced( expr->type );
type = TypedefModifierRemoveOnly( type );
if( type->id == TYP_VOID ) {
PTreeErrorExpr( expr, ERR_EXPR_IS_VOID );
} else if( type->id == TYP_CLASS ) {
TYPE bool_type = GetBasicType( TYP_BOOL );
expr = CastImplicit( expr, bool_type, CNV_EXPR, &diagConvertToBool );
} else {
operand = expr;
zero = NodeIntegralConstant( 0, GetBasicType( TYP_SINT ) );
expr = NodeBinary( CO_NE, expr, zero );
expr = PTreeCopySrcLocation( expr, operand );
expr = AnalyseOperator( expr );
}
return expr;
}
PTREE NodeRemoveCasts( // REMOVE CASTING FROM NODE
PTREE node ) // - starting node
{
while( NodeIsBinaryOp( node, CO_CONVERT ) ) {
node = PTreeOpRight( node );
}
return node;
}
PTREE NodeRemoveCastsCommas( // REMOVE COMMAS, DTORING, CASTING FROM NODE
PTREE node ) // - starting node
{
PTREE not_used; // - dtoring, not used
return *NodeReturnSrc( &node, ¬_used );
}
PTREE NodeSymbolNoRef( // FILL IN NODE FOR A SYMBOL, NO REF. SETTING
PTREE expr, // - node
SYMBOL sym, // - symbol
SEARCH_RESULT *result ) // - search result
{
if( NULL == expr ) {
expr = PTreeAlloc();
}
expr->u.symcg.result = result;
expr->u.symcg.symbol = sym;
expr->op = PT_SYMBOL;
expr->flags |= PTF_LVALUE | PTF_LV_CHECKED;
expr->type = sym->sym_type;
expr->cgop = CO_NAME_NORMAL;
if( result != NULL ) {
ScopeResultErrLocn( result, &expr->locn );
if( result->sym != NULL ) {
expr->cgop = CO_NAME_CONVERT;
}
}
return expr;
}
PTREE NodeSymbol( // CONVERT NODE TO BE SYMBOL
PTREE expr, // - node
SYMBOL sym, // - symbol
SEARCH_RESULT *result ) // - search result
{
sym = SymMarkRefed( sym );
return NodeSymbolNoRef( expr, sym, result );
}
PTREE NodeSymbolCallee( // MAKE SYMBOL FOR A CALLEE
PTREE expr, // - node
SYMBOL sym, // - symbol
SEARCH_RESULT *result ) // - search result
{
if( ! SymIsVirtual( sym ) ) {
sym = SymMarkRefed( sym );
}
return NodeSymbolNoRef( expr, sym, result );
}
PTREE MakeNodeSymbol( // MAKE PT_SYMBOL NODE FROM SYMBOL
SYMBOL sym ) // - symbol
{
sym = SymMarkRefed( sym );
if( NULL != StructType( sym->sym_type ) ) {
sym->flag |= PTF_MEMORY_EXACT;
}
return NodeSymbolNoRef( NULL, sym, NULL );
}
PTREE NodeMakeCallee( // MAKE A CALLEE NODE
SYMBOL func ) // - function
{
if( ! SymIsVirtual( func ) ) {
func = SymMarkRefed( func );
}
return NodeSymbolNoRef( NULL, func, NULL );
}
PTREE NodeGetConstantNode( // RETURN CONSTANT-INT NODE
PTREE node ) // - node
{
for( ; ; ) {
if( NodeIsBinaryOp( node, CO_CONVERT ) ) {
if( NULL == IntegralType( NodeType( node ) ) ) {
node = NULL;
break;
}
node = node->u.subtree[1];
} else if( NodeIsBinaryOp( node, CO_COMMA ) ) {
node = node->u.subtree[1];
} else {
break;
}
}
if( node != NULL )
switch( node->op ) {
case PT_INT_CONSTANT :
if( NULL == IntegralType( NodeType( node ) ) ) {
node = NULL;
}
break;
case PT_SYMBOL :
if( SymIsConstantInt( node->u.symcg.symbol ) ) {
node = PTreeOpRight( node );
} else {
node = NULL;
}
break;
default :
node = NULL;
break;
}
return node;
}
boolean NodeIsConstantInt( // TEST IF A CONSTANT INT NODE
PTREE node ) // - node
{
boolean retn; // - TRUE ==> is zero constant
if( node == NULL ) {
retn = FALSE;
} else {
node = NodeRemoveCasts( PTreeOp( &node ) );
switch( node->op ) {
case PT_INT_CONSTANT :
retn = ( NULL != IntegralType( node->type ) );
break;
case PT_SYMBOL :
retn = SymIsConstantInt( node->u.symcg.symbol );
break;
default :
retn = FALSE;
break;
}
}
return retn;
}
boolean NodeIsConstant( // TEST IF NODE IS A CONSTANT
PTREE node ) // - node
{
boolean retn; // - TRUE ==> is constant
if( TypeIsConst( NodeType( node ) ) ) {
retn = TRUE;
} else {
switch( node->op ) {
case PT_INT_CONSTANT : // these are typed w/o TF1_CONST
case PT_STRING_CONSTANT :
case PT_FLOATING_CONSTANT :
retn = TRUE;
break;
default :
retn = FALSE;
break;
}
}
return retn;
}
unsigned long NodeConstantValue(// GET CONSTANT VALUE FOR A NODE
PTREE node ) // - a constant node
{
SYMBOL sym; // - symbol for node
unsigned long retn; // - return value
node = NodeRemoveCasts( node );
switch( node->op ) {
case PT_INT_CONSTANT :
retn = node->u.int_constant;
break;
case PT_SYMBOL :
sym = node->u.symcg.symbol;
retn = sym->u.sval;
break;
DbgDefault( "non-constant node passed to NodeConstantValue" );
}
return retn;
}
static boolean nodeGetConstant // TEST IF CONSTANT AND GET VALUE
( PTREE node // - potential constant node
, INT_CONSTANT* pval ) // - addr[ value ]
{
boolean retn; // - return: TRUE ==> is integral constant
SYMBOL sym; // - symbol for node
if( node == NULL ) {
retn = FALSE;
} else {
node = NodeRemoveCasts( PTreeOp( &node ) );
switch( node->op ) {
case PT_INT_CONSTANT :
pval->type = TypedefModifierRemoveOnly( node->type );
pval->value = node->u.int64_constant;
retn = TRUE;
break;
case PT_SYMBOL :
sym = node->u.symcg.symbol;
retn = SymIsConstantInt( sym );
if( retn ) {
SymConstantValue( sym, pval );
}
break;
default :
retn = FALSE;
break;
}
}
return retn;
}
boolean NodeIsIntConstant // TEST IF INTEGRAL CONSTANT AND GET VALUE
( PTREE node // - potential constant node
, INT_CONSTANT* pval ) // - addr[ value ]
{
boolean retn; // - return: TRUE ==> is integral constant
if( NULL == IntegralType( node->type ) ) {
retn = FALSE;
} else {
retn = nodeGetConstant( node, pval );
}
return retn;
}
boolean NodeIsZeroConstant( // TEST IF A ZERO INTEGER CONSTANT
PTREE node ) // - node
{
boolean retn; // - TRUE ==> is zero constant
INT_CONSTANT icon; // - integral constant
if( nodeGetConstant( node, &icon ) ) {
retn = ( 0 == icon.value.u._32[0] && 0 == icon.value.u._32[1] );
} else {
retn = FALSE;
}
return retn;
}
PTREE NodeFromConstSym( // BUILD CONSTANT NODE FROM CONSTANT SYMBOL
SYMBOL con ) // - constant symbol
{
INT_CONSTANT icon; // - integral constant
PTREE retn; // - new entry
con = SymConstantValue( con, &icon );
retn = PTreeInt64Constant( icon.value, TYP_SLONG64 );
retn->type = SymUnmodifiedType( con );
return retn;
}
void NodeFreeSearchResult( // FREE SEARCH_RESULT FROM A NODE
PTREE node ) // - the node
{
if( node->op == PT_SYMBOL ) {
ScopeFreeResult( node->u.symcg.result );
node->u.symcg.result = NULL;
}
}
static boolean nodeIsAssignment(// TEST IF NODE IS "=" or initialization
PTREE node ) // - node
{
return NodeIsBinaryOp( node, CO_EQUAL )
|| NodeIsBinaryOp( node, CO_INIT )
|| NodeIsBinaryOp( node, CO_EQUAL_REF )
|| NodeIsBinaryOp( node, CO_INIT_REF );
}
static PTREE nodeSimplifyComma( // REMOVE CO_TRASH TO GET RVALUE
PTREE node ) // - the node
{
PTREE trash; // - trash node
PTREE op; // - assignment operator
PTREE dup; // - duplicating node
PTREE right; // - node to right of comma
if( NodeIsBinaryOp( node, CO_COMMA ) ) {
right = node->u.subtree[1];
if( right->op == PT_SYMBOL ) {
op = PTreeOpLeft( node );
if( nodeIsAssignment( op ) ) {
dup = PTreeOpLeft( op );
if( ( dup->op == PT_SYMBOL )
&&( dup->u.symcg.symbol == right->u.symcg.symbol ) ) {
trash = node;
node = node->u.subtree[0];
trash->u.subtree[0] = NULL;
NodeFreeDupedExpr( trash );
}
}
} else if( ( right->op == PT_DUP_EXPR )
&&( right->u.dup.subtree[0] == NULL ) ) {
op = PTreeOpLeft( node );
if( nodeIsAssignment( op ) ) {
dup = PTreeOpLeft( op );
if( ( dup->op == PT_DUP_EXPR )
&&( dup->u.dup.node == right->u.dup.node ) ) {
DbgUseless();
op->u.subtree[0] = dup->u.dup.subtree[0];
PTreeFree( dup );
trash = node;
node = node->u.subtree[0];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?