1
0
Fork 0
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:
Alena Laskavaia 2010-04-15 02:22:56 +00:00
parent 697b118ca5
commit 234a20224a
12 changed files with 154 additions and 108 deletions

View file

@ -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

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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();
} }
} }

View file

@ -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);
} }
} }

View file

@ -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);
} }

View file

@ -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;
} }

View file

@ -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$

View file

@ -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 {
/** /**

View file

@ -22,7 +22,7 @@ public interface INodeFactory {
IConnectorNode createConnectorNode(); IConnectorNode createConnectorNode();
ILabeledNode createLabeledNode(String label); IBranchNode createLabeledNode(String label);
IStartNode createStartNode(); IStartNode createStartNode();

View file

@ -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);
} }
} }

View file

@ -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.