From 1264b58a40f46cf9eaf29696904f276310b878ed Mon Sep 17 00:00:00 2001 From: Andrew Niefer Date: Wed, 2 Feb 2005 19:35:14 +0000 Subject: [PATCH] visit if statements iteratively to avoid stack overflow when there are huge numbers of else ifs --- .../internal/core/dom/parser/c/CVisitor.java | 32 ++++++++++++++++--- .../core/dom/parser/cpp/CPPVisitor.java | 31 +++++++++++++++--- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java index 6ed9fcd8540..e6ad2b91fb1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java @@ -1505,7 +1505,34 @@ public class CVisitor { 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 ){ + //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 ){ switch( action.processStatement( statement ) ){ case CPPBaseVisitorAction.PROCESS_ABORT : return false; @@ -1531,11 +1558,6 @@ public class CVisitor { if( !visitExpression( ((IASTDoStatement)statement).getCondition(), action ) ) return false; } else if( statement instanceof IASTGotoStatement ){ 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 ){ if( !visitName( ((IASTLabelStatement)statement).getName(), action ) ) return false; } else if( statement instanceof IASTReturnStatement ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index ff6ea0362b7..e9222890366 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -950,12 +950,39 @@ public class CPPVisitor { 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 action * @return */ 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 ){ switch( action.processStatement( statement ) ){ case CPPBaseVisitorAction.PROCESS_ABORT : return false; @@ -981,10 +1008,6 @@ public class CPPVisitor { if( !visitExpression( ((IASTDoStatement)statement).getCondition(), action ) ) return false; } else if( statement instanceof IASTGotoStatement ){ 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 ){ if( !visitName( ((IASTLabelStatement)statement).getName(), action ) ) return false; } else if( statement instanceof IASTReturnStatement ){