mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-29 03:45:35 +02:00
Added try block support in control flow graph
This commit is contained in:
parent
3ec7ac60fa
commit
b632454589
2 changed files with 58 additions and 0 deletions
|
@ -48,6 +48,8 @@ import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTryBlockStatement;
|
||||
|
||||
/**
|
||||
* This class creates C control flow graph
|
||||
|
@ -163,12 +165,41 @@ public class ControlFlowGraphBuilder {
|
|||
return node;
|
||||
} else if (body == null) {
|
||||
// skip - sometimes body is empty such as no else
|
||||
} else if (body instanceof ICPPASTTryBlockStatement) {
|
||||
return createTry(prev, (ICPPASTTryBlockStatement) body);
|
||||
} else {
|
||||
System.err.println("unknown statement for cfg: " + body); //$NON-NLS-1$
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param prev
|
||||
* @param body
|
||||
* @return
|
||||
*/
|
||||
private IBasicBlock createTry(IBasicBlock prev,
|
||||
ICPPASTTryBlockStatement body) {
|
||||
DecisionNode ifNode = factory.createDecisionNode(body);
|
||||
addOutgoing(prev, ifNode);
|
||||
IConnectorNode mergeNode = factory.createConnectorNode();
|
||||
ifNode.setMergeNode(mergeNode);
|
||||
IBranchNode thenNode = factory.createBranchNode(IBranchNode.THEN);
|
||||
addOutgoing(ifNode, thenNode);
|
||||
IBasicBlock then = createSubGraph(thenNode, body.getTryBody());
|
||||
addJump(then, mergeNode);
|
||||
ICPPASTCatchHandler[] catchHandlers = body.getCatchHandlers();
|
||||
for (int i = 0; i < catchHandlers.length; i++) {
|
||||
ICPPASTCatchHandler handler = catchHandlers[i];
|
||||
IBranchNode handlerNode = factory
|
||||
.createBranchNode(handler.getDeclaration());
|
||||
addOutgoing(ifNode, handlerNode);
|
||||
IBasicBlock els = createSubGraph(handlerNode, handler.getCatchBody());
|
||||
addJump(els, mergeNode);
|
||||
}
|
||||
return mergeNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param body
|
||||
* @return
|
||||
|
|
|
@ -333,4 +333,31 @@ public class ControlFlowGraphTest extends CodanFastCxxAstTestCase {
|
|||
public IChecker getChecker() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// int foo() {
|
||||
// void * p;
|
||||
// try {
|
||||
// *p = 1;
|
||||
// } catch (int e) {
|
||||
// };
|
||||
// }
|
||||
public void test_try() {
|
||||
buildAndCheck_cpp(getAboveComment());
|
||||
IStartNode startNode = graph.getStartNode();
|
||||
IPlainNode decl = (IPlainNode) startNode.getOutgoing();
|
||||
IDecisionNode des = (IDecisionNode) decl.getOutgoing();
|
||||
//assertEquals("", data(des));
|
||||
IPlainNode bThen = (IPlainNode) branchEnd(des, IBranchNode.THEN);
|
||||
assertEquals("*p = 1;", data(bThen));
|
||||
IBasicBlock bElse = null;
|
||||
IBasicBlock[] outgoingNodes = des.getOutgoingNodes();
|
||||
for (int i = 1; i < outgoingNodes.length; i++) {
|
||||
IBasicBlock iBasicBlock = outgoingNodes[i];
|
||||
IBranchNode bn = (IBranchNode) iBasicBlock;
|
||||
bElse = bn;
|
||||
}
|
||||
IBasicBlock m2 = jumpEnd(bThen);
|
||||
IBasicBlock m1 = jumpEnd(bElse);
|
||||
assertSame(m1, m2);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue