mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-24 16:53:50 +02:00
visit if statements iteratively to avoid stack overflow when there are huge numbers of else ifs
This commit is contained in:
parent
71309151e2
commit
1264b58a40
2 changed files with 54 additions and 9 deletions
|
@ -1505,7 +1505,34 @@ public class CVisitor {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean visitIfStatement( IASTIfStatement ifStatement, CBaseVisitorAction action ){
|
||||||
|
while( ifStatement != null ){
|
||||||
|
if( action.processStatements ){
|
||||||
|
switch( action.processStatement( ifStatement ) ){
|
||||||
|
case CPPBaseVisitorAction.PROCESS_ABORT : return false;
|
||||||
|
case CPPBaseVisitorAction.PROCESS_SKIP : return true;
|
||||||
|
default : break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( !visitExpression( ifStatement.getCondition(), action ) ) return false;
|
||||||
|
if( !visitStatement( ifStatement.getThenClause(), action ) ) return false;
|
||||||
|
if( ifStatement.getElseClause() != null ){
|
||||||
|
IASTStatement statement = ifStatement.getElseClause();
|
||||||
|
if( statement instanceof IASTIfStatement ){
|
||||||
|
ifStatement = (IASTIfStatement) statement;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( !visitStatement( statement, action ) ) return false;
|
||||||
|
}
|
||||||
|
ifStatement = null;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
public static boolean visitStatement( IASTStatement statement, CBaseVisitorAction action ){
|
public static boolean visitStatement( IASTStatement statement, CBaseVisitorAction action ){
|
||||||
|
//handle if's in a non-recursive manner to avoid stack overflows in case of huge number of elses
|
||||||
|
if( statement instanceof IASTIfStatement )
|
||||||
|
return visitIfStatement( (IASTIfStatement) statement, action );
|
||||||
|
|
||||||
if( action.processStatements ){
|
if( action.processStatements ){
|
||||||
switch( action.processStatement( statement ) ){
|
switch( action.processStatement( statement ) ){
|
||||||
case CPPBaseVisitorAction.PROCESS_ABORT : return false;
|
case CPPBaseVisitorAction.PROCESS_ABORT : return false;
|
||||||
|
@ -1531,11 +1558,6 @@ public class CVisitor {
|
||||||
if( !visitExpression( ((IASTDoStatement)statement).getCondition(), action ) ) return false;
|
if( !visitExpression( ((IASTDoStatement)statement).getCondition(), action ) ) return false;
|
||||||
} else if( statement instanceof IASTGotoStatement ){
|
} else if( statement instanceof IASTGotoStatement ){
|
||||||
if( !visitName( ((IASTGotoStatement)statement).getName(), action ) ) return false;
|
if( !visitName( ((IASTGotoStatement)statement).getName(), action ) ) return false;
|
||||||
} else if( statement instanceof IASTIfStatement ){
|
|
||||||
if( !visitExpression( ((IASTIfStatement) statement ).getCondition(), action ) ) return false;
|
|
||||||
if( !visitStatement( ((IASTIfStatement) statement ).getThenClause(), action ) ) return false;
|
|
||||||
if( ((IASTIfStatement) statement ).getElseClause() != null )
|
|
||||||
if( !visitStatement( ((IASTIfStatement) statement ).getElseClause(), action ) ) return false;
|
|
||||||
} else if( statement instanceof IASTLabelStatement ){
|
} else if( statement instanceof IASTLabelStatement ){
|
||||||
if( !visitName( ((IASTLabelStatement)statement).getName(), action ) ) return false;
|
if( !visitName( ((IASTLabelStatement)statement).getName(), action ) ) return false;
|
||||||
} else if( statement instanceof IASTReturnStatement ){
|
} else if( statement instanceof IASTReturnStatement ){
|
||||||
|
|
|
@ -950,12 +950,39 @@ public class CPPVisitor {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean visitIfStatement( IASTIfStatement ifStatement, CPPBaseVisitorAction action ){
|
||||||
|
while( ifStatement != null ){
|
||||||
|
if( action.processStatements ){
|
||||||
|
switch( action.processStatement( ifStatement ) ){
|
||||||
|
case CPPBaseVisitorAction.PROCESS_ABORT : return false;
|
||||||
|
case CPPBaseVisitorAction.PROCESS_SKIP : return true;
|
||||||
|
default : break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( !visitExpression( ifStatement.getCondition(), action ) ) return false;
|
||||||
|
if( !visitStatement( ifStatement.getThenClause(), action ) ) return false;
|
||||||
|
if( ifStatement.getElseClause() != null ){
|
||||||
|
IASTStatement statement = ifStatement.getElseClause();
|
||||||
|
if( statement instanceof IASTIfStatement ){
|
||||||
|
ifStatement = (IASTIfStatement) statement;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( !visitStatement( statement, action ) ) return false;
|
||||||
|
}
|
||||||
|
ifStatement = null;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @param body
|
* @param body
|
||||||
* @param action
|
* @param action
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static boolean visitStatement(IASTStatement statement, CPPBaseVisitorAction action) {
|
public static boolean visitStatement(IASTStatement statement, CPPBaseVisitorAction action) {
|
||||||
|
//handle if's in a non-recursive manner to avoid stack overflows in case of huge number of elses
|
||||||
|
if( statement instanceof IASTIfStatement )
|
||||||
|
return visitIfStatement( (IASTIfStatement) statement, action );
|
||||||
|
|
||||||
if( action.processStatements ){
|
if( action.processStatements ){
|
||||||
switch( action.processStatement( statement ) ){
|
switch( action.processStatement( statement ) ){
|
||||||
case CPPBaseVisitorAction.PROCESS_ABORT : return false;
|
case CPPBaseVisitorAction.PROCESS_ABORT : return false;
|
||||||
|
@ -981,10 +1008,6 @@ public class CPPVisitor {
|
||||||
if( !visitExpression( ((IASTDoStatement)statement).getCondition(), action ) ) return false;
|
if( !visitExpression( ((IASTDoStatement)statement).getCondition(), action ) ) return false;
|
||||||
} else if( statement instanceof IASTGotoStatement ){
|
} else if( statement instanceof IASTGotoStatement ){
|
||||||
if( !visitName( ((IASTGotoStatement)statement).getName(), action ) ) return false;
|
if( !visitName( ((IASTGotoStatement)statement).getName(), action ) ) return false;
|
||||||
} else if( statement instanceof IASTIfStatement ){
|
|
||||||
if( !visitExpression( ((IASTIfStatement) statement ).getCondition(), action ) ) return false;
|
|
||||||
if( !visitStatement( ((IASTIfStatement) statement ).getThenClause(), action ) ) return false;
|
|
||||||
if( !visitStatement( ((IASTIfStatement) statement ).getElseClause(), action ) ) return false;
|
|
||||||
} else if( statement instanceof IASTLabelStatement ){
|
} else if( statement instanceof IASTLabelStatement ){
|
||||||
if( !visitName( ((IASTLabelStatement)statement).getName(), action ) ) return false;
|
if( !visitName( ((IASTLabelStatement)statement).getName(), action ) ) return false;
|
||||||
} else if( statement instanceof IASTReturnStatement ){
|
} else if( statement instanceof IASTReturnStatement ){
|
||||||
|
|
Loading…
Add table
Reference in a new issue