mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-10 17:55:39 +02:00
- added support for break and continue
This commit is contained in:
parent
697b118ca5
commit
234a20224a
12 changed files with 154 additions and 108 deletions
|
@ -21,12 +21,13 @@ import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IJumpNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IJumpNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.ILabeledNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBranchNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IPlainNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IPlainNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTContinueStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
|
||||||
|
@ -49,6 +50,8 @@ public class ControlFlowGraphBuilder {
|
||||||
Collection<IBasicBlock> dead;
|
Collection<IBasicBlock> dead;
|
||||||
CxxExitNode returnExit;
|
CxxExitNode returnExit;
|
||||||
CxxNodeFactory factory = new CxxNodeFactory();
|
CxxNodeFactory factory = new CxxNodeFactory();
|
||||||
|
IConnectorNode outerBreak;
|
||||||
|
IConnectorNode outerContinue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param def
|
* @param def
|
||||||
|
@ -99,6 +102,14 @@ public class ControlFlowGraphBuilder {
|
||||||
node.setStartNode(start);
|
node.setStartNode(start);
|
||||||
addOutgoing(prev, node);
|
addOutgoing(prev, node);
|
||||||
return node;
|
return node;
|
||||||
|
} else if (body instanceof IASTBreakStatement) {
|
||||||
|
if (outerBreak != null)
|
||||||
|
return addJump(prev, outerBreak);
|
||||||
|
return prev;
|
||||||
|
} else if (body instanceof IASTContinueStatement) {
|
||||||
|
if (outerContinue != null)
|
||||||
|
return addJump(prev, outerContinue);
|
||||||
|
return prev;
|
||||||
} else if (body instanceof IASTSwitchStatement) {
|
} else if (body instanceof IASTSwitchStatement) {
|
||||||
return createSwitch(prev, (IASTSwitchStatement) body);
|
return createSwitch(prev, (IASTSwitchStatement) body);
|
||||||
}
|
}
|
||||||
|
@ -116,14 +127,14 @@ public class ControlFlowGraphBuilder {
|
||||||
addOutgoing(prev, ifNode);
|
addOutgoing(prev, ifNode);
|
||||||
IConnectorNode mergeNode = factory.createConnectorNode();
|
IConnectorNode mergeNode = factory.createConnectorNode();
|
||||||
ifNode.setMergeNode(mergeNode);
|
ifNode.setMergeNode(mergeNode);
|
||||||
ILabeledNode thenNode = factory.createLabeledNode(ILabeledNode.THEN);
|
IBranchNode thenNode = factory.createLabeledNode(IBranchNode.THEN);
|
||||||
addOutgoing(ifNode, thenNode);
|
addOutgoing(ifNode, thenNode);
|
||||||
IBasicBlock then = createSubGraph(thenNode, body.getThenClause());
|
IBasicBlock then = createSubGraph(thenNode, body.getThenClause());
|
||||||
addOutgoing(then, mergeNode);
|
addJump(then, mergeNode);
|
||||||
ILabeledNode elseNode = factory.createLabeledNode(ILabeledNode.ELSE);
|
IBranchNode elseNode = factory.createLabeledNode(IBranchNode.ELSE);
|
||||||
addOutgoing(ifNode, elseNode);
|
addOutgoing(ifNode, elseNode);
|
||||||
IBasicBlock els = createSubGraph(elseNode, body.getElseClause());
|
IBasicBlock els = createSubGraph(elseNode, body.getElseClause());
|
||||||
addOutgoing(els, mergeNode);
|
addJump(els, mergeNode);
|
||||||
return mergeNode;
|
return mergeNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,12 +155,12 @@ public class ControlFlowGraphBuilder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param switchNode
|
* @param switchNode
|
||||||
* @param conn
|
* @param mergeNode
|
||||||
* @param def
|
* @param def
|
||||||
* @param body
|
* @param body
|
||||||
*/
|
*/
|
||||||
private void createSwitchBody(DecisionNode switchNode, ConnectorNode conn,
|
private void createSwitchBody(DecisionNode switchNode,
|
||||||
IASTStatement body) {
|
ConnectorNode mergeNode, IASTStatement body) {
|
||||||
if (!(body instanceof IASTCompoundStatement))
|
if (!(body instanceof IASTCompoundStatement))
|
||||||
return; // bad
|
return; // bad
|
||||||
IASTCompoundStatement comp = (IASTCompoundStatement) body;
|
IASTCompoundStatement comp = (IASTCompoundStatement) body;
|
||||||
|
@ -159,28 +170,38 @@ public class ControlFlowGraphBuilder {
|
||||||
IASTNode elem = children[i];
|
IASTNode elem = children[i];
|
||||||
if (elem instanceof IASTCaseStatement) {
|
if (elem instanceof IASTCaseStatement) {
|
||||||
IASTCaseStatement caseSt = (IASTCaseStatement) elem;
|
IASTCaseStatement caseSt = (IASTCaseStatement) elem;
|
||||||
ILabeledNode lbl = factory.createLabeledNode(caseSt);
|
}
|
||||||
|
if (elem instanceof IASTDefaultStatement) {
|
||||||
|
IBranchNode lbl = factory
|
||||||
|
.createLabeledNode(IBranchNode.DEFAULT);
|
||||||
if (!(prev instanceof IExitNode) && prev != switchNode)
|
if (!(prev instanceof IExitNode) && prev != switchNode)
|
||||||
addOutgoing(prev, lbl);
|
addOutgoing(prev, lbl);
|
||||||
addOutgoing(switchNode, lbl);
|
addOutgoing(switchNode, lbl);
|
||||||
prev = lbl;
|
prev = lbl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (elem instanceof IASTCaseStatement
|
||||||
|
|| elem instanceof IASTDefaultStatement) {
|
||||||
|
IBranchNode lbl = null;
|
||||||
|
if (elem instanceof IASTCaseStatement) {
|
||||||
|
IASTCaseStatement caseSt = (IASTCaseStatement) elem;
|
||||||
|
lbl = factory.createLabeledNode(caseSt);
|
||||||
|
} else if (elem instanceof IASTDefaultStatement) {
|
||||||
|
lbl = factory.createLabeledNode(IBranchNode.DEFAULT);
|
||||||
|
}
|
||||||
|
if (!(prev instanceof IExitNode) && prev != switchNode) {
|
||||||
|
IConnectorNode here = factory.createConnectorNode();
|
||||||
|
addJump(prev, here);
|
||||||
|
addOutgoing(lbl, here);
|
||||||
|
prev = here;
|
||||||
|
} else {
|
||||||
|
prev = lbl;
|
||||||
|
}
|
||||||
|
addOutgoing(switchNode, lbl);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (elem instanceof IASTBreakStatement) {
|
if (elem instanceof IASTBreakStatement) {
|
||||||
JumpNode nBreak = (JumpNode) factory.createJumpNode();
|
prev = addJump(prev, mergeNode);
|
||||||
addOutgoing(prev, nBreak);
|
|
||||||
nBreak.setJump(conn, false);
|
|
||||||
conn.addIncoming(nBreak);
|
|
||||||
prev = nBreak;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (elem instanceof IASTDefaultStatement) {
|
|
||||||
ILabeledNode lbl = factory
|
|
||||||
.createLabeledNode(ILabeledNode.DEFAULT);
|
|
||||||
if (!(prev instanceof IExitNode) && prev != switchNode)
|
|
||||||
addOutgoing(prev, lbl);
|
|
||||||
addOutgoing(switchNode, lbl);
|
|
||||||
prev = lbl;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
IBasicBlock last = createSubGraph(prev, elem);
|
IBasicBlock last = createSubGraph(prev, elem);
|
||||||
|
@ -200,32 +221,38 @@ public class ControlFlowGraphBuilder {
|
||||||
addOutgoing(prev, init);
|
addOutgoing(prev, init);
|
||||||
prev = init;
|
prev = init;
|
||||||
// add continue connector
|
// add continue connector
|
||||||
IConnectorNode nContinue2 = factory.createConnectorNode();
|
IConnectorNode beforeCheck = factory.createConnectorNode();
|
||||||
addOutgoing(prev, nContinue2);
|
addOutgoing(prev, beforeCheck);
|
||||||
// decision node
|
// decision node
|
||||||
CxxDecisionNode decision = factory.createDecisionNode(forNode
|
CxxDecisionNode decision = factory.createDecisionNode(forNode
|
||||||
.getConditionExpression());
|
.getConditionExpression());
|
||||||
addOutgoing(nContinue2, decision);
|
addOutgoing(beforeCheck, decision);
|
||||||
// add break connector
|
// add break connector
|
||||||
IConnectorNode nBreak = factory.createConnectorNode();
|
IConnectorNode nBreak = factory.createConnectorNode();
|
||||||
decision.setMergeNode(nBreak);
|
decision.setMergeNode(nBreak);
|
||||||
// create body and jump to continue node
|
// create body and jump to continue node
|
||||||
ILabeledNode loopStart = factory.createLabeledNode(ILabeledNode.THEN);
|
IBranchNode loopStart = factory.createLabeledNode(IBranchNode.THEN);
|
||||||
addOutgoing(decision, loopStart);
|
addOutgoing(decision, loopStart);
|
||||||
|
// set break/continue
|
||||||
|
IConnectorNode nContinue = factory.createConnectorNode();
|
||||||
|
IConnectorNode savedContinue = outerContinue;
|
||||||
|
IConnectorNode savedBreak = outerBreak;
|
||||||
|
outerContinue = nContinue;
|
||||||
|
outerBreak = nBreak;
|
||||||
IBasicBlock endBody = createSubGraph(loopStart, forNode.getBody());
|
IBasicBlock endBody = createSubGraph(loopStart, forNode.getBody());
|
||||||
|
outerContinue = savedContinue;
|
||||||
|
outerBreak = savedBreak;
|
||||||
// inc
|
// inc
|
||||||
IPlainNode inc = factory.createPlainNode(forNode
|
IPlainNode inc = factory.createPlainNode(forNode
|
||||||
.getIterationExpression());
|
.getIterationExpression());
|
||||||
addOutgoing(endBody, inc);
|
addOutgoing(endBody, nContinue);
|
||||||
JumpNode jumpContinue = new JumpNode();
|
addOutgoing(nContinue, inc);
|
||||||
addOutgoing(inc, jumpContinue);
|
|
||||||
jumpContinue.setJump(nContinue2, true);
|
|
||||||
// connect with backward link
|
// connect with backward link
|
||||||
addOutgoing(jumpContinue, nContinue2);
|
addJump(inc, beforeCheck, true);
|
||||||
// add "else" branch
|
// add "else" branch
|
||||||
ILabeledNode loopEnd = factory.createLabeledNode(ILabeledNode.ELSE);
|
IBranchNode loopEnd = factory.createLabeledNode(IBranchNode.ELSE);
|
||||||
addOutgoing(decision, loopEnd);
|
addOutgoing(decision, loopEnd);
|
||||||
addOutgoing(loopEnd, nBreak);
|
addJump(loopEnd, nBreak);
|
||||||
return nBreak;
|
return nBreak;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,18 +273,23 @@ public class ControlFlowGraphBuilder {
|
||||||
IConnectorNode nBreak = factory.createConnectorNode();
|
IConnectorNode nBreak = factory.createConnectorNode();
|
||||||
decision.setMergeNode(nBreak);
|
decision.setMergeNode(nBreak);
|
||||||
// create body and jump to continue node
|
// create body and jump to continue node
|
||||||
ILabeledNode loopStart = factory.createLabeledNode(ILabeledNode.THEN);
|
IBranchNode loopStart = factory.createLabeledNode(IBranchNode.THEN);
|
||||||
addOutgoing(decision, loopStart);
|
addOutgoing(decision, loopStart);
|
||||||
|
// set break/continue
|
||||||
|
IConnectorNode savedContinue = outerContinue;
|
||||||
|
IConnectorNode savedBreak = outerBreak;
|
||||||
|
outerContinue = nContinue;
|
||||||
|
outerBreak = nBreak;
|
||||||
IBasicBlock endBody = createSubGraph(loopStart, body.getBody());
|
IBasicBlock endBody = createSubGraph(loopStart, body.getBody());
|
||||||
JumpNode jumpContinue = new JumpNode();
|
// restore
|
||||||
addOutgoing(endBody, jumpContinue);
|
outerContinue = savedContinue;
|
||||||
jumpContinue.setJump(nContinue, true);
|
outerBreak = savedBreak;
|
||||||
// connect with backward link
|
// backward jump
|
||||||
addOutgoing(jumpContinue, nContinue);
|
addJump(endBody, nContinue, true);
|
||||||
// connect with else branch
|
// connect with else branch
|
||||||
ILabeledNode loopEnd = factory.createLabeledNode(ILabeledNode.ELSE);
|
IBranchNode loopEnd = factory.createLabeledNode(IBranchNode.ELSE);
|
||||||
addOutgoing(decision, loopEnd);
|
addOutgoing(decision, loopEnd);
|
||||||
addOutgoing(loopEnd, nBreak);
|
addJump(loopEnd, nBreak);
|
||||||
return nBreak;
|
return nBreak;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,32 +297,55 @@ public class ControlFlowGraphBuilder {
|
||||||
// create body and jump to continue node
|
// create body and jump to continue node
|
||||||
IConnectorNode loopStart = factory.createConnectorNode();
|
IConnectorNode loopStart = factory.createConnectorNode();
|
||||||
addOutgoing(prev, loopStart);
|
addOutgoing(prev, loopStart);
|
||||||
|
// continue/break
|
||||||
|
IConnectorNode nContinue = factory.createConnectorNode();
|
||||||
|
IConnectorNode nBreak = factory.createConnectorNode();
|
||||||
|
IConnectorNode savedContinue = outerContinue;
|
||||||
|
IConnectorNode savedBreak = outerBreak;
|
||||||
|
outerContinue = nContinue;
|
||||||
|
outerBreak = nBreak;
|
||||||
IBasicBlock endBody = createSubGraph(loopStart, body.getBody());
|
IBasicBlock endBody = createSubGraph(loopStart, body.getBody());
|
||||||
|
// restore
|
||||||
|
outerContinue = savedContinue;
|
||||||
|
outerBreak = savedBreak;
|
||||||
// add continue connector
|
// add continue connector
|
||||||
IConnectorNode nContinue = factory.createLabeledNode("continue");
|
|
||||||
addOutgoing(endBody, nContinue);
|
addOutgoing(endBody, nContinue);
|
||||||
// decision node
|
// decision node
|
||||||
CxxDecisionNode decision = factory.createDecisionNode(body
|
CxxDecisionNode decision = factory.createDecisionNode(body
|
||||||
.getCondition());
|
.getCondition());
|
||||||
addOutgoing(nContinue, decision);
|
addOutgoing(nContinue, decision);
|
||||||
// then branch
|
// then branch
|
||||||
ILabeledNode thenNode = factory.createLabeledNode(ILabeledNode.THEN);
|
IBranchNode thenNode = factory.createLabeledNode(IBranchNode.THEN);
|
||||||
addOutgoing(decision, thenNode);
|
addOutgoing(decision, thenNode);
|
||||||
IJumpNode jumpToStart = factory.createJumpNode();
|
IJumpNode jumpToStart = factory.createJumpNode();
|
||||||
addOutgoing(thenNode, jumpToStart);
|
addOutgoing(thenNode, jumpToStart);
|
||||||
((JumpNode)jumpToStart).setBackward(true);
|
((JumpNode) jumpToStart).setBackward(true);
|
||||||
// connect with backward link
|
// connect with backward link
|
||||||
addOutgoing(jumpToStart, loopStart);
|
addOutgoing(jumpToStart, loopStart);
|
||||||
// connect with else branch
|
// connect with else branch
|
||||||
ILabeledNode loopEnd = factory.createLabeledNode(ILabeledNode.ELSE);
|
IBranchNode loopEnd = factory.createLabeledNode(IBranchNode.ELSE);
|
||||||
addOutgoing(decision, loopEnd);
|
addOutgoing(decision, loopEnd);
|
||||||
// add break connector
|
// add break connector
|
||||||
IConnectorNode nBreak = factory.createConnectorNode();
|
|
||||||
decision.setMergeNode(nBreak);
|
decision.setMergeNode(nBreak);
|
||||||
addOutgoing(loopEnd, nBreak);
|
addJump(loopEnd, nBreak);
|
||||||
return nBreak;
|
return nBreak;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IJumpNode addJump(IBasicBlock prev, IConnectorNode conn) {
|
||||||
|
return addJump(prev, conn, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IJumpNode addJump(IBasicBlock prev, IConnectorNode conn,
|
||||||
|
boolean backward) {
|
||||||
|
if (prev instanceof IJumpNode)
|
||||||
|
return (IJumpNode) prev;
|
||||||
|
IJumpNode jump = factory.createJumpNode();
|
||||||
|
addOutgoing(prev, jump);
|
||||||
|
addOutgoing(jump, conn);
|
||||||
|
((JumpNode) jump).setBackward(backward);
|
||||||
|
return jump;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param prev
|
* @param prev
|
||||||
* @param node
|
* @param node
|
||||||
|
|
|
@ -10,17 +10,17 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.codan.core.cxx.internal.model.cfg;
|
package org.eclipse.cdt.codan.core.cxx.internal.model.cfg;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.LabeledNode;
|
import org.eclipse.cdt.codan.internal.core.cfg.BranchNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: add description
|
* TODO: add description
|
||||||
*/
|
*/
|
||||||
public class CxxLabeledNode extends LabeledNode {
|
public class CxxBranchNode extends BranchNode {
|
||||||
private IASTNode labelData;
|
private IASTNode labelData;
|
||||||
|
|
||||||
|
|
||||||
CxxLabeledNode(IASTNode label) {
|
CxxBranchNode(IASTNode label) {
|
||||||
super(label.getRawSignature());
|
super(label.getRawSignature());
|
||||||
this.labelData = label;
|
this.labelData = label;
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@ package org.eclipse.cdt.codan.core.cxx.internal.model.cfg;
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.AbstractBasicBlock;
|
import org.eclipse.cdt.codan.internal.core.cfg.AbstractBasicBlock;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.ILabeledNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBranchNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.INodeFactory;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.INodeFactory;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IPlainNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IPlainNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.NodeFactory;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.NodeFactory;
|
||||||
|
@ -61,8 +61,8 @@ public class CxxNodeFactory extends NodeFactory implements INodeFactory {
|
||||||
* @param caseSt
|
* @param caseSt
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public ILabeledNode createLabeledNode(IASTNode caseSt) {
|
public IBranchNode createLabeledNode(IASTNode caseSt) {
|
||||||
ILabeledNode node = createLabeledNode(caseSt.getRawSignature());
|
IBranchNode node = createLabeledNode(caseSt.getRawSignature());
|
||||||
((AbstractBasicBlock) node).setData(caseSt);
|
((AbstractBasicBlock) node).setData(caseSt);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,15 +10,15 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.codan.internal.core.cfg;
|
package org.eclipse.cdt.codan.internal.core.cfg;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.ILabeledNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBranchNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: add description
|
* TODO: add description
|
||||||
*/
|
*/
|
||||||
public class LabeledNode extends ConnectorNode implements ILabeledNode {
|
public class BranchNode extends PlainNode implements IBranchNode {
|
||||||
private String label;
|
protected String label;
|
||||||
|
|
||||||
public LabeledNode(String label) {
|
public BranchNode(String label) {
|
||||||
super();
|
super();
|
||||||
this.label = label;
|
this.label = label;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ public class LabeledNode extends ConnectorNode implements ILabeledNode {
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
* @see
|
* @see
|
||||||
* org.eclipse.cdt.codan.provisional.core.model.cfg.ILabeledNode#getLabel()
|
* org.eclipse.cdt.codan.provisional.core.model.cfg.IBranchNode#getLabel()
|
||||||
*/
|
*/
|
||||||
public String getLabel() {
|
public String getLabel() {
|
||||||
return label;
|
return label;
|
||||||
|
@ -35,8 +35,6 @@ public class LabeledNode extends ConnectorNode implements ILabeledNode {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toStringData() {
|
public String toStringData() {
|
||||||
if (getData() == null)
|
return label;
|
||||||
return label + ":";
|
|
||||||
return getData().toString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -22,7 +22,7 @@ import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IControlFlowGraph;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IControlFlowGraph;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.ILabeledNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBranchNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.ISingleOutgoing;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.ISingleOutgoing;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ public class ControlFlowGraph implements IControlFlowGraph {
|
||||||
print(((IDecisionNode) node).getMergeNode());
|
print(((IDecisionNode) node).getMergeNode());
|
||||||
} else if (node instanceof ISingleOutgoing) {
|
} else if (node instanceof ISingleOutgoing) {
|
||||||
IBasicBlock next = ((ISingleOutgoing) node).getOutgoing();
|
IBasicBlock next = ((ISingleOutgoing) node).getOutgoing();
|
||||||
if (!(next instanceof IConnectorNode && !(next instanceof ILabeledNode)))
|
if (!(next instanceof IConnectorNode && !(next instanceof IBranchNode)))
|
||||||
print(next);
|
print(next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
||||||
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBranchNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ public class DecisionNode extends AbstractSingleIncomingNode implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addOutgoing(IBasicBlock node) {
|
public void addOutgoing(IBasicBlock node) {
|
||||||
IConnectorNode cnode = (IConnectorNode) node; // cast to throw CCE
|
IBranchNode cnode = (IBranchNode) node; // cast to throw CCE
|
||||||
next.add(cnode);
|
next.add(cnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.eclipse.cdt.codan.internal.core.cfg;
|
package org.eclipse.cdt.codan.internal.core.cfg;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IPlainNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IPlainNode;
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ import org.eclipse.cdt.codan.provisional.core.model.cfg.IPlainNode;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class PlainNode extends AbstractSingleIncomingNode implements IPlainNode {
|
public class PlainNode extends AbstractSingleIncomingNode implements IPlainNode {
|
||||||
IBasicBlock next;
|
protected IBasicBlock next;
|
||||||
|
|
||||||
public PlainNode() {
|
public PlainNode() {
|
||||||
super();
|
super();
|
||||||
|
@ -28,9 +29,6 @@ public class PlainNode extends AbstractSingleIncomingNode implements IPlainNode
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOutgoing(IBasicBlock exit) {
|
public void setOutgoing(IBasicBlock exit) {
|
||||||
if (this.next != null)
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Cannot modify already exiting connector"); //$NON-NLS-1$
|
|
||||||
this.next = exit;
|
this.next = exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,8 @@ package org.eclipse.cdt.codan.provisional.core.model.cfg;
|
||||||
/**
|
/**
|
||||||
* Node that represent empty operator with label, such as case branch or label
|
* Node that represent empty operator with label, such as case branch or label
|
||||||
*/
|
*/
|
||||||
public interface ILabeledNode extends IConnectorNode {
|
public interface IBranchNode extends IBasicBlock, ISingleIncoming,
|
||||||
|
ISingleOutgoing {
|
||||||
public static String THEN = "then"; //$NON-NLS-1$
|
public static String THEN = "then"; //$NON-NLS-1$
|
||||||
public static String ELSE = "else"; //$NON-NLS-1$
|
public static String ELSE = "else"; //$NON-NLS-1$
|
||||||
public static String DEFAULT = "default"; //$NON-NLS-1$
|
public static String DEFAULT = "default"; //$NON-NLS-1$
|
|
@ -4,7 +4,7 @@ package org.eclipse.cdt.codan.provisional.core.model.cfg;
|
||||||
*
|
*
|
||||||
* Interface for decision node. This node represent condition node in the graph,
|
* Interface for decision node. This node represent condition node in the graph,
|
||||||
* it has one incoming arc and many outgoing, each of outgoing node should be
|
* it has one incoming arc and many outgoing, each of outgoing node should be
|
||||||
* ILabeledNode
|
* IBranchNode
|
||||||
*/
|
*/
|
||||||
public interface IDecisionNode extends IBasicBlock, ISingleIncoming {
|
public interface IDecisionNode extends IBasicBlock, ISingleIncoming {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,7 +22,7 @@ public interface INodeFactory {
|
||||||
|
|
||||||
IConnectorNode createConnectorNode();
|
IConnectorNode createConnectorNode();
|
||||||
|
|
||||||
ILabeledNode createLabeledNode(String label);
|
IBranchNode createLabeledNode(String label);
|
||||||
|
|
||||||
IStartNode createStartNode();
|
IStartNode createStartNode();
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ import org.eclipse.cdt.codan.internal.core.cfg.ConnectorNode;
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.DecisionNode;
|
import org.eclipse.cdt.codan.internal.core.cfg.DecisionNode;
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.ExitNode;
|
import org.eclipse.cdt.codan.internal.core.cfg.ExitNode;
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.JumpNode;
|
import org.eclipse.cdt.codan.internal.core.cfg.JumpNode;
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.LabeledNode;
|
import org.eclipse.cdt.codan.internal.core.cfg.BranchNode;
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.PlainNode;
|
import org.eclipse.cdt.codan.internal.core.cfg.PlainNode;
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.StartNode;
|
import org.eclipse.cdt.codan.internal.core.cfg.StartNode;
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ public class NodeFactory implements INodeFactory {
|
||||||
return new ExitNode();
|
return new ExitNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ILabeledNode createLabeledNode(String label) {
|
public IBranchNode createLabeledNode(String label) {
|
||||||
return new LabeledNode(label);
|
return new BranchNode(label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import org.eclipse.cdt.codan.provisional.core.model.cfg.IControlFlowGraph;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IJumpNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IJumpNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.ILabeledNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBranchNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.ISingleOutgoing;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.ISingleOutgoing;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
|
||||||
import org.eclipse.cdt.codan.ui.cfgview.ControlFlowGraphPlugin;
|
import org.eclipse.cdt.codan.ui.cfgview.ControlFlowGraphPlugin;
|
||||||
|
@ -131,10 +131,9 @@ public class ControlFlowGraphView extends ViewPart {
|
||||||
}
|
}
|
||||||
blocks.add(((IDecisionNode) parent).getMergeNode());
|
blocks.add(((IDecisionNode) parent).getMergeNode());
|
||||||
return blocks.toArray();
|
return blocks.toArray();
|
||||||
} else if (parent instanceof ILabeledNode) {
|
} else if (parent instanceof IBranchNode) {
|
||||||
Collection<IBasicBlock> blocks = getFlat(
|
Collection<IBasicBlock> blocks = getFlat(((IBranchNode) parent)
|
||||||
((ILabeledNode) parent).getOutgoing(),
|
.getOutgoing(), new ArrayList<IBasicBlock>());
|
||||||
new ArrayList<IBasicBlock>());
|
|
||||||
return blocks.toArray();
|
return blocks.toArray();
|
||||||
}
|
}
|
||||||
return new Object[0];
|
return new Object[0];
|
||||||
|
@ -143,6 +142,25 @@ public class ControlFlowGraphView extends ViewPart {
|
||||||
public boolean hasChildren(Object parent) {
|
public boolean hasChildren(Object parent) {
|
||||||
return getChildren(parent).length > 0;
|
return getChildren(parent).length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param list
|
||||||
|
* @param startNode
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Collection<IBasicBlock> getFlat(IBasicBlock node,
|
||||||
|
Collection<IBasicBlock> list) {
|
||||||
|
list.add(node);
|
||||||
|
if (node instanceof IJumpNode)
|
||||||
|
return list;
|
||||||
|
if (node instanceof ISingleOutgoing) {
|
||||||
|
getFlat(((ISingleOutgoing) node).getOutgoing(), list);
|
||||||
|
} else if (node instanceof IDecisionNode) {
|
||||||
|
getFlat(((IDecisionNode) node).getMergeNode().getOutgoing(),
|
||||||
|
list);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewLabelProvider extends LabelProvider {
|
class ViewLabelProvider extends LabelProvider {
|
||||||
|
@ -154,13 +172,11 @@ public class ControlFlowGraphView extends ViewPart {
|
||||||
strdata = ((AbstractBasicBlock) obj).toStringData();
|
strdata = ((AbstractBasicBlock) obj).toStringData();
|
||||||
}
|
}
|
||||||
if (strdata == null || strdata.length() == 0) {
|
if (strdata == null || strdata.length() == 0) {
|
||||||
if (obj instanceof ILabeledNode) {
|
if (obj instanceof IConnectorNode) {
|
||||||
strdata = strdata+blockHexLabel(obj);
|
|
||||||
} else if (obj instanceof IConnectorNode) {
|
|
||||||
strdata = blockHexLabel(obj);
|
strdata = blockHexLabel(obj);
|
||||||
} else if (obj instanceof IJumpNode) {
|
} else if (obj instanceof IJumpNode) {
|
||||||
strdata = blockHexLabel(((IJumpNode) obj).getJumpNode());
|
strdata = blockHexLabel(((IJumpNode) obj).getJumpNode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return obj.getClass().getSimpleName() + ": " + strdata;
|
return obj.getClass().getSimpleName() + ": " + strdata;
|
||||||
}
|
}
|
||||||
|
@ -184,7 +200,7 @@ public class ControlFlowGraphView extends ViewPart {
|
||||||
imageKey = "start.png";
|
imageKey = "start.png";
|
||||||
else if (obj instanceof IJumpNode)
|
else if (obj instanceof IJumpNode)
|
||||||
imageKey = "jump.png";
|
imageKey = "jump.png";
|
||||||
else if (obj instanceof ILabeledNode)
|
else if (obj instanceof IBranchNode)
|
||||||
imageKey = "labeled.png";
|
imageKey = "labeled.png";
|
||||||
else if (obj instanceof IConnectorNode)
|
else if (obj instanceof IConnectorNode)
|
||||||
imageKey = "connector.png";
|
imageKey = "connector.png";
|
||||||
|
@ -199,29 +215,6 @@ public class ControlFlowGraphView extends ViewPart {
|
||||||
public ControlFlowGraphView() {
|
public ControlFlowGraphView() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param list
|
|
||||||
* @param startNode
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public Collection<IBasicBlock> getFlat(IBasicBlock node,
|
|
||||||
Collection<IBasicBlock> list) {
|
|
||||||
list.add(node);
|
|
||||||
if (node instanceof IConnectorNode
|
|
||||||
&& !((IConnectorNode) node).hasBackwardIncoming() &&
|
|
||||||
!(node instanceof ILabeledNode)) {
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
if (node instanceof IJumpNode)
|
|
||||||
return list;
|
|
||||||
if (node instanceof ISingleOutgoing) {
|
|
||||||
getFlat(((ISingleOutgoing) node).getOutgoing(), list);
|
|
||||||
} else if (node instanceof IDecisionNode) {
|
|
||||||
getFlat(((IDecisionNode) node).getMergeNode().getOutgoing(), list);
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a callback that will allow us to create the viewer and initialize
|
* This is a callback that will allow us to create the viewer and initialize
|
||||||
* it.
|
* it.
|
||||||
|
|
Loading…
Add table
Reference in a new issue