diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java index 1c2318c87d5..0e0012475d2 100644 --- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java @@ -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.IExitNode; 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.IStartNode; import org.eclipse.cdt.core.dom.ast.IASTBreakStatement; import org.eclipse.cdt.core.dom.ast.IASTCaseStatement; 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.IASTDefaultStatement; import org.eclipse.cdt.core.dom.ast.IASTDoStatement; @@ -49,6 +50,8 @@ public class ControlFlowGraphBuilder { Collection dead; CxxExitNode returnExit; CxxNodeFactory factory = new CxxNodeFactory(); + IConnectorNode outerBreak; + IConnectorNode outerContinue; /** * @param def @@ -99,6 +102,14 @@ public class ControlFlowGraphBuilder { node.setStartNode(start); addOutgoing(prev, 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) { return createSwitch(prev, (IASTSwitchStatement) body); } @@ -116,14 +127,14 @@ public class ControlFlowGraphBuilder { addOutgoing(prev, ifNode); IConnectorNode mergeNode = factory.createConnectorNode(); ifNode.setMergeNode(mergeNode); - ILabeledNode thenNode = factory.createLabeledNode(ILabeledNode.THEN); + IBranchNode thenNode = factory.createLabeledNode(IBranchNode.THEN); addOutgoing(ifNode, thenNode); IBasicBlock then = createSubGraph(thenNode, body.getThenClause()); - addOutgoing(then, mergeNode); - ILabeledNode elseNode = factory.createLabeledNode(ILabeledNode.ELSE); + addJump(then, mergeNode); + IBranchNode elseNode = factory.createLabeledNode(IBranchNode.ELSE); addOutgoing(ifNode, elseNode); IBasicBlock els = createSubGraph(elseNode, body.getElseClause()); - addOutgoing(els, mergeNode); + addJump(els, mergeNode); return mergeNode; } @@ -144,12 +155,12 @@ public class ControlFlowGraphBuilder { /** * @param switchNode - * @param conn + * @param mergeNode * @param def * @param body */ - private void createSwitchBody(DecisionNode switchNode, ConnectorNode conn, - IASTStatement body) { + private void createSwitchBody(DecisionNode switchNode, + ConnectorNode mergeNode, IASTStatement body) { if (!(body instanceof IASTCompoundStatement)) return; // bad IASTCompoundStatement comp = (IASTCompoundStatement) body; @@ -159,28 +170,38 @@ public class ControlFlowGraphBuilder { IASTNode elem = children[i]; if (elem instanceof IASTCaseStatement) { 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) addOutgoing(prev, lbl); addOutgoing(switchNode, lbl); prev = lbl; 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) { - JumpNode nBreak = (JumpNode) factory.createJumpNode(); - 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; + prev = addJump(prev, mergeNode); continue; } IBasicBlock last = createSubGraph(prev, elem); @@ -200,32 +221,38 @@ public class ControlFlowGraphBuilder { addOutgoing(prev, init); prev = init; // add continue connector - IConnectorNode nContinue2 = factory.createConnectorNode(); - addOutgoing(prev, nContinue2); + IConnectorNode beforeCheck = factory.createConnectorNode(); + addOutgoing(prev, beforeCheck); // decision node CxxDecisionNode decision = factory.createDecisionNode(forNode .getConditionExpression()); - addOutgoing(nContinue2, decision); + addOutgoing(beforeCheck, decision); // add break connector IConnectorNode nBreak = factory.createConnectorNode(); decision.setMergeNode(nBreak); // create body and jump to continue node - ILabeledNode loopStart = factory.createLabeledNode(ILabeledNode.THEN); + IBranchNode loopStart = factory.createLabeledNode(IBranchNode.THEN); 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()); + outerContinue = savedContinue; + outerBreak = savedBreak; // inc IPlainNode inc = factory.createPlainNode(forNode .getIterationExpression()); - addOutgoing(endBody, inc); - JumpNode jumpContinue = new JumpNode(); - addOutgoing(inc, jumpContinue); - jumpContinue.setJump(nContinue2, true); + addOutgoing(endBody, nContinue); + addOutgoing(nContinue, inc); // connect with backward link - addOutgoing(jumpContinue, nContinue2); + addJump(inc, beforeCheck, true); // add "else" branch - ILabeledNode loopEnd = factory.createLabeledNode(ILabeledNode.ELSE); + IBranchNode loopEnd = factory.createLabeledNode(IBranchNode.ELSE); addOutgoing(decision, loopEnd); - addOutgoing(loopEnd, nBreak); + addJump(loopEnd, nBreak); return nBreak; } @@ -246,18 +273,23 @@ public class ControlFlowGraphBuilder { IConnectorNode nBreak = factory.createConnectorNode(); decision.setMergeNode(nBreak); // create body and jump to continue node - ILabeledNode loopStart = factory.createLabeledNode(ILabeledNode.THEN); + IBranchNode loopStart = factory.createLabeledNode(IBranchNode.THEN); addOutgoing(decision, loopStart); + // set break/continue + IConnectorNode savedContinue = outerContinue; + IConnectorNode savedBreak = outerBreak; + outerContinue = nContinue; + outerBreak = nBreak; IBasicBlock endBody = createSubGraph(loopStart, body.getBody()); - JumpNode jumpContinue = new JumpNode(); - addOutgoing(endBody, jumpContinue); - jumpContinue.setJump(nContinue, true); - // connect with backward link - addOutgoing(jumpContinue, nContinue); + // restore + outerContinue = savedContinue; + outerBreak = savedBreak; + // backward jump + addJump(endBody, nContinue, true); // connect with else branch - ILabeledNode loopEnd = factory.createLabeledNode(ILabeledNode.ELSE); + IBranchNode loopEnd = factory.createLabeledNode(IBranchNode.ELSE); addOutgoing(decision, loopEnd); - addOutgoing(loopEnd, nBreak); + addJump(loopEnd, nBreak); return nBreak; } @@ -265,32 +297,55 @@ public class ControlFlowGraphBuilder { // create body and jump to continue node IConnectorNode loopStart = factory.createConnectorNode(); 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()); + // restore + outerContinue = savedContinue; + outerBreak = savedBreak; // add continue connector - IConnectorNode nContinue = factory.createLabeledNode("continue"); addOutgoing(endBody, nContinue); // decision node CxxDecisionNode decision = factory.createDecisionNode(body .getCondition()); addOutgoing(nContinue, decision); // then branch - ILabeledNode thenNode = factory.createLabeledNode(ILabeledNode.THEN); + IBranchNode thenNode = factory.createLabeledNode(IBranchNode.THEN); addOutgoing(decision, thenNode); IJumpNode jumpToStart = factory.createJumpNode(); addOutgoing(thenNode, jumpToStart); - ((JumpNode)jumpToStart).setBackward(true); + ((JumpNode) jumpToStart).setBackward(true); // connect with backward link addOutgoing(jumpToStart, loopStart); // connect with else branch - ILabeledNode loopEnd = factory.createLabeledNode(ILabeledNode.ELSE); + IBranchNode loopEnd = factory.createLabeledNode(IBranchNode.ELSE); addOutgoing(decision, loopEnd); // add break connector - IConnectorNode nBreak = factory.createConnectorNode(); decision.setMergeNode(nBreak); - addOutgoing(loopEnd, nBreak); + addJump(loopEnd, 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 node diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxLabeledNode.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxBranchNode.java similarity index 86% rename from codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxLabeledNode.java rename to codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxBranchNode.java index b2237cbd7d2..04c5debfda6 100644 --- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxLabeledNode.java +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxBranchNode.java @@ -10,17 +10,17 @@ *******************************************************************************/ 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; /** * TODO: add description */ -public class CxxLabeledNode extends LabeledNode { +public class CxxBranchNode extends BranchNode { private IASTNode labelData; - CxxLabeledNode(IASTNode label) { + CxxBranchNode(IASTNode label) { super(label.getRawSignature()); this.labelData = label; } diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxNodeFactory.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxNodeFactory.java index 1bea3e1059c..eec6afd05a1 100644 --- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxNodeFactory.java +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxNodeFactory.java @@ -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.provisional.core.model.cfg.IDecisionNode; 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.IPlainNode; import org.eclipse.cdt.codan.provisional.core.model.cfg.NodeFactory; @@ -61,8 +61,8 @@ public class CxxNodeFactory extends NodeFactory implements INodeFactory { * @param caseSt * @return */ - public ILabeledNode createLabeledNode(IASTNode caseSt) { - ILabeledNode node = createLabeledNode(caseSt.getRawSignature()); + public IBranchNode createLabeledNode(IASTNode caseSt) { + IBranchNode node = createLabeledNode(caseSt.getRawSignature()); ((AbstractBasicBlock) node).setData(caseSt); return node; } diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/LabeledNode.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/BranchNode.java similarity index 68% rename from codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/LabeledNode.java rename to codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/BranchNode.java index 36eeee5180f..976530c846a 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/LabeledNode.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/BranchNode.java @@ -10,15 +10,15 @@ *******************************************************************************/ 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 */ -public class LabeledNode extends ConnectorNode implements ILabeledNode { - private String label; +public class BranchNode extends PlainNode implements IBranchNode { + protected String label; - public LabeledNode(String label) { + public BranchNode(String label) { super(); this.label = label; } @@ -27,7 +27,7 @@ public class LabeledNode extends ConnectorNode implements ILabeledNode { * (non-Javadoc) * * @see - * org.eclipse.cdt.codan.provisional.core.model.cfg.ILabeledNode#getLabel() + * org.eclipse.cdt.codan.provisional.core.model.cfg.IBranchNode#getLabel() */ public String getLabel() { return label; @@ -35,8 +35,6 @@ public class LabeledNode extends ConnectorNode implements ILabeledNode { @Override public String toStringData() { - if (getData() == null) - return label + ":"; - return getData().toString(); + return label; } } diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ControlFlowGraph.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ControlFlowGraph.java index a310b642fdc..78818babda1 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ControlFlowGraph.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ControlFlowGraph.java @@ -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.IDecisionNode; 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.IStartNode; @@ -85,7 +85,7 @@ public class ControlFlowGraph implements IControlFlowGraph { print(((IDecisionNode) node).getMergeNode()); } else if (node instanceof ISingleOutgoing) { IBasicBlock next = ((ISingleOutgoing) node).getOutgoing(); - if (!(next instanceof IConnectorNode && !(next instanceof ILabeledNode))) + if (!(next instanceof IConnectorNode && !(next instanceof IBranchNode))) print(next); } } diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/DecisionNode.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/DecisionNode.java index facf2676fdb..0e37cdfc4dd 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/DecisionNode.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/DecisionNode.java @@ -15,6 +15,7 @@ import java.util.Iterator; import java.util.List; 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.IDecisionNode; @@ -35,7 +36,7 @@ public class DecisionNode extends AbstractSingleIncomingNode implements @Override public void addOutgoing(IBasicBlock node) { - IConnectorNode cnode = (IConnectorNode) node; // cast to throw CCE + IBranchNode cnode = (IBranchNode) node; // cast to throw CCE next.add(cnode); } diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/PlainNode.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/PlainNode.java index 6e25c51ad4a..6b44eadc09b 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/PlainNode.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/PlainNode.java @@ -1,6 +1,7 @@ package org.eclipse.cdt.codan.internal.core.cfg; import java.util.Iterator; + import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock; 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 { - IBasicBlock next; + protected IBasicBlock next; public PlainNode() { super(); @@ -28,9 +29,6 @@ public class PlainNode extends AbstractSingleIncomingNode implements IPlainNode } public void setOutgoing(IBasicBlock exit) { - if (this.next != null) - throw new IllegalArgumentException( - "Cannot modify already exiting connector"); //$NON-NLS-1$ this.next = exit; } diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/ILabeledNode.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/IBranchNode.java similarity index 90% rename from codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/ILabeledNode.java rename to codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/IBranchNode.java index bae40b81e6b..13c1dff66d6 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/ILabeledNode.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/IBranchNode.java @@ -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 */ -public interface ILabeledNode extends IConnectorNode { +public interface IBranchNode extends IBasicBlock, ISingleIncoming, + ISingleOutgoing { public static String THEN = "then"; //$NON-NLS-1$ public static String ELSE = "else"; //$NON-NLS-1$ public static String DEFAULT = "default"; //$NON-NLS-1$ diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/IDecisionNode.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/IDecisionNode.java index de3602f42a1..eabcf482650 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/IDecisionNode.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/IDecisionNode.java @@ -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, * it has one incoming arc and many outgoing, each of outgoing node should be - * ILabeledNode + * IBranchNode */ public interface IDecisionNode extends IBasicBlock, ISingleIncoming { /** diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/INodeFactory.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/INodeFactory.java index b7ba30acb81..d37832dc826 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/INodeFactory.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/INodeFactory.java @@ -22,7 +22,7 @@ public interface INodeFactory { IConnectorNode createConnectorNode(); - ILabeledNode createLabeledNode(String label); + IBranchNode createLabeledNode(String label); IStartNode createStartNode(); diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/NodeFactory.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/NodeFactory.java index 48b330aa2b4..f5839296f22 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/NodeFactory.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/NodeFactory.java @@ -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.ExitNode; 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.StartNode; @@ -101,7 +101,7 @@ public class NodeFactory implements INodeFactory { return new ExitNode(); } - public ILabeledNode createLabeledNode(String label) { - return new LabeledNode(label); + public IBranchNode createLabeledNode(String label) { + return new BranchNode(label); } } diff --git a/codan/org.eclipse.cdt.codan.ui.cfgview/src/org/eclipse/cdt/codan/ui/cfgview/views/ControlFlowGraphView.java b/codan/org.eclipse.cdt.codan.ui.cfgview/src/org/eclipse/cdt/codan/ui/cfgview/views/ControlFlowGraphView.java index f3f05073bf8..218004ab9fd 100644 --- a/codan/org.eclipse.cdt.codan.ui.cfgview/src/org/eclipse/cdt/codan/ui/cfgview/views/ControlFlowGraphView.java +++ b/codan/org.eclipse.cdt.codan.ui.cfgview/src/org/eclipse/cdt/codan/ui/cfgview/views/ControlFlowGraphView.java @@ -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.IExitNode; 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.IStartNode; import org.eclipse.cdt.codan.ui.cfgview.ControlFlowGraphPlugin; @@ -131,10 +131,9 @@ public class ControlFlowGraphView extends ViewPart { } blocks.add(((IDecisionNode) parent).getMergeNode()); return blocks.toArray(); - } else if (parent instanceof ILabeledNode) { - Collection blocks = getFlat( - ((ILabeledNode) parent).getOutgoing(), - new ArrayList()); + } else if (parent instanceof IBranchNode) { + Collection blocks = getFlat(((IBranchNode) parent) + .getOutgoing(), new ArrayList()); return blocks.toArray(); } return new Object[0]; @@ -143,6 +142,25 @@ public class ControlFlowGraphView extends ViewPart { public boolean hasChildren(Object parent) { return getChildren(parent).length > 0; } + + /** + * @param list + * @param startNode + * @return + */ + public Collection getFlat(IBasicBlock node, + Collection 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 { @@ -154,13 +172,11 @@ public class ControlFlowGraphView extends ViewPart { strdata = ((AbstractBasicBlock) obj).toStringData(); } if (strdata == null || strdata.length() == 0) { - if (obj instanceof ILabeledNode) { - strdata = strdata+blockHexLabel(obj); - } else if (obj instanceof IConnectorNode) { + if (obj instanceof IConnectorNode) { strdata = blockHexLabel(obj); } else if (obj instanceof IJumpNode) { strdata = blockHexLabel(((IJumpNode) obj).getJumpNode()); - } + } } return obj.getClass().getSimpleName() + ": " + strdata; } @@ -184,7 +200,7 @@ public class ControlFlowGraphView extends ViewPart { imageKey = "start.png"; else if (obj instanceof IJumpNode) imageKey = "jump.png"; - else if (obj instanceof ILabeledNode) + else if (obj instanceof IBranchNode) imageKey = "labeled.png"; else if (obj instanceof IConnectorNode) imageKey = "connector.png"; @@ -199,29 +215,6 @@ public class ControlFlowGraphView extends ViewPart { public ControlFlowGraphView() { } - /** - * @param list - * @param startNode - * @return - */ - public Collection getFlat(IBasicBlock node, - Collection 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 * it.