Skip to main content
summaryrefslogtreecommitdiffstats
path: root/codan
diff options
context:
space:
mode:
authorAlena Laskavaia2010-04-17 01:58:12 +0000
committerAlena Laskavaia2010-04-17 01:58:12 +0000
commit5a5d22c50d923c826fdcb77797fcc151862cfc61 (patch)
tree8301ba83f652db3784cea9c730fb797c0ca17585 /codan
parent0f78d0c5fdf8de60395010c08cb2f78e957ab9a8 (diff)
downloadorg.eclipse.cdt-5a5d22c50d923c826fdcb77797fcc151862cfc61.tar.gz
org.eclipse.cdt-5a5d22c50d923c826fdcb77797fcc151862cfc61.tar.xz
org.eclipse.cdt-5a5d22c50d923c826fdcb77797fcc151862cfc61.zip
- added more tests and support for goto/label statements
Diffstat (limited to 'codan')
-rw-r--r--codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java82
-rw-r--r--codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxNodeFactory.java4
-rw-r--r--codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java209
-rw-r--r--codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractBasicBlock.java2
-rw-r--r--codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ControlFlowGraph.java13
-rw-r--r--codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/INodeFactory.java2
-rw-r--r--codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/NodeFactory.java2
-rw-r--r--codan/org.eclipse.cdt.codan.ui.cfgview/src/org/eclipse/cdt/codan/ui/cfgview/views/ControlFlowGraphView.java10
8 files changed, 268 insertions, 56 deletions
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 0e0012475d2..599ba4edf72 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
@@ -12,6 +12,7 @@ package org.eclipse.cdt.codan.core.cxx.internal.model.cfg;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import org.eclipse.cdt.codan.internal.core.cfg.AbstractBasicBlock;
import org.eclipse.cdt.codan.internal.core.cfg.ConnectorNode;
@@ -34,7 +35,9 @@ import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
+import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
+import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
@@ -52,6 +55,7 @@ public class ControlFlowGraphBuilder {
CxxNodeFactory factory = new CxxNodeFactory();
IConnectorNode outerBreak;
IConnectorNode outerContinue;
+ HashMap<String, IBasicBlock> labels = new HashMap<String, IBasicBlock>(0);
/**
* @param def
@@ -68,7 +72,9 @@ public class ControlFlowGraphBuilder {
returnExit.setStartNode(start);
addOutgoing(last, returnExit);
}
- return new CxxControlFlowGraph(start, exits);
+ CxxControlFlowGraph graph = new CxxControlFlowGraph(start, exits);
+ graph.setUnconnectedNodes(dead);
+ return graph;
}
/**
@@ -112,12 +118,55 @@ public class ControlFlowGraphBuilder {
return prev;
} else if (body instanceof IASTSwitchStatement) {
return createSwitch(prev, (IASTSwitchStatement) body);
+ } else if (body instanceof IASTLabelStatement) {
+ IASTLabelStatement ast = (IASTLabelStatement) body;
+ String labelName = ast.getName().toString();
+ IBranchNode labNode = (IBranchNode) labels.get(labelName);
+ IConnectorNode conn;
+ if (labNode != null) {
+ conn = (IConnectorNode) labNode.getOutgoing();
+ addOutgoing(prev, labNode);
+ } else {
+ // labeled statement contains of connector for jumps, branch for
+ // label
+ // and nested statement
+ conn = createLabelNodes(prev, labelName);
+ }
+ return createSubGraph(conn, ast.getNestedStatement());
+ } else if (body instanceof IASTGotoStatement) {
+ IASTGotoStatement ast = (IASTGotoStatement)body;
+ String labelName = ast.getName().toString();
+ IConnectorNode conn;
+ IBranchNode labNode = (IBranchNode) labels.get(labelName);
+ if (labNode!=null) {
+ conn = (IConnectorNode) labNode.getOutgoing();
+ } else {
+ conn = createLabelNodes(null, labelName);
+ }
+ IJumpNode gotoNode = factory.createJumpNode();
+ ((JumpNode) gotoNode).setJump(conn, labNode!=null);
+ addOutgoing(prev, gotoNode);
+ return gotoNode;
}
return prev;
}
/**
* @param prev
+ * @param labelName
+ * @return
+ */
+ protected IConnectorNode createLabelNodes(IBasicBlock prev, String labelName) {
+ IBranchNode branch = factory.createBranchNode(labelName);
+ if (prev!=null) addOutgoing(prev, branch);
+ labels.put(labelName, branch);
+ IConnectorNode conn = factory.createConnectorNode();
+ addOutgoing(branch, conn);
+ return conn;
+ }
+
+ /**
+ * @param prev
* @param body
* @return
*/
@@ -127,11 +176,11 @@ public class ControlFlowGraphBuilder {
addOutgoing(prev, ifNode);
IConnectorNode mergeNode = factory.createConnectorNode();
ifNode.setMergeNode(mergeNode);
- IBranchNode thenNode = factory.createLabeledNode(IBranchNode.THEN);
+ IBranchNode thenNode = factory.createBranchNode(IBranchNode.THEN);
addOutgoing(ifNode, thenNode);
IBasicBlock then = createSubGraph(thenNode, body.getThenClause());
addJump(then, mergeNode);
- IBranchNode elseNode = factory.createLabeledNode(IBranchNode.ELSE);
+ IBranchNode elseNode = factory.createBranchNode(IBranchNode.ELSE);
addOutgoing(ifNode, elseNode);
IBasicBlock els = createSubGraph(elseNode, body.getElseClause());
addJump(els, mergeNode);
@@ -173,7 +222,7 @@ public class ControlFlowGraphBuilder {
}
if (elem instanceof IASTDefaultStatement) {
IBranchNode lbl = factory
- .createLabeledNode(IBranchNode.DEFAULT);
+ .createBranchNode(IBranchNode.DEFAULT);
if (!(prev instanceof IExitNode) && prev != switchNode)
addOutgoing(prev, lbl);
addOutgoing(switchNode, lbl);
@@ -185,9 +234,9 @@ public class ControlFlowGraphBuilder {
IBranchNode lbl = null;
if (elem instanceof IASTCaseStatement) {
IASTCaseStatement caseSt = (IASTCaseStatement) elem;
- lbl = factory.createLabeledNode(caseSt);
+ lbl = factory.createBranchNode(caseSt);
} else if (elem instanceof IASTDefaultStatement) {
- lbl = factory.createLabeledNode(IBranchNode.DEFAULT);
+ lbl = factory.createBranchNode(IBranchNode.DEFAULT);
}
if (!(prev instanceof IExitNode) && prev != switchNode) {
IConnectorNode here = factory.createConnectorNode();
@@ -231,7 +280,7 @@ public class ControlFlowGraphBuilder {
IConnectorNode nBreak = factory.createConnectorNode();
decision.setMergeNode(nBreak);
// create body and jump to continue node
- IBranchNode loopStart = factory.createLabeledNode(IBranchNode.THEN);
+ IBranchNode loopStart = factory.createBranchNode(IBranchNode.THEN);
addOutgoing(decision, loopStart);
// set break/continue
IConnectorNode nContinue = factory.createConnectorNode();
@@ -250,7 +299,7 @@ public class ControlFlowGraphBuilder {
// connect with backward link
addJump(inc, beforeCheck, true);
// add "else" branch
- IBranchNode loopEnd = factory.createLabeledNode(IBranchNode.ELSE);
+ IBranchNode loopEnd = factory.createBranchNode(IBranchNode.ELSE);
addOutgoing(decision, loopEnd);
addJump(loopEnd, nBreak);
return nBreak;
@@ -273,7 +322,7 @@ public class ControlFlowGraphBuilder {
IConnectorNode nBreak = factory.createConnectorNode();
decision.setMergeNode(nBreak);
// create body and jump to continue node
- IBranchNode loopStart = factory.createLabeledNode(IBranchNode.THEN);
+ IBranchNode loopStart = factory.createBranchNode(IBranchNode.THEN);
addOutgoing(decision, loopStart);
// set break/continue
IConnectorNode savedContinue = outerContinue;
@@ -287,7 +336,7 @@ public class ControlFlowGraphBuilder {
// backward jump
addJump(endBody, nContinue, true);
// connect with else branch
- IBranchNode loopEnd = factory.createLabeledNode(IBranchNode.ELSE);
+ IBranchNode loopEnd = factory.createBranchNode(IBranchNode.ELSE);
addOutgoing(decision, loopEnd);
addJump(loopEnd, nBreak);
return nBreak;
@@ -315,7 +364,7 @@ public class ControlFlowGraphBuilder {
.getCondition());
addOutgoing(nContinue, decision);
// then branch
- IBranchNode thenNode = factory.createLabeledNode(IBranchNode.THEN);
+ IBranchNode thenNode = factory.createBranchNode(IBranchNode.THEN);
addOutgoing(decision, thenNode);
IJumpNode jumpToStart = factory.createJumpNode();
addOutgoing(thenNode, jumpToStart);
@@ -323,7 +372,7 @@ public class ControlFlowGraphBuilder {
// connect with backward link
addOutgoing(jumpToStart, loopStart);
// connect with else branch
- IBranchNode loopEnd = factory.createLabeledNode(IBranchNode.ELSE);
+ IBranchNode loopEnd = factory.createBranchNode(IBranchNode.ELSE);
addOutgoing(decision, loopEnd);
// add break connector
decision.setMergeNode(nBreak);
@@ -339,6 +388,8 @@ public class ControlFlowGraphBuilder {
boolean backward) {
if (prev instanceof IJumpNode)
return (IJumpNode) prev;
+ if (prev instanceof IExitNode)
+ return null;
IJumpNode jump = factory.createJumpNode();
addOutgoing(prev, jump);
addOutgoing(jump, conn);
@@ -351,12 +402,13 @@ public class ControlFlowGraphBuilder {
* @param node
*/
private void addOutgoing(IBasicBlock prev, IBasicBlock node) {
- if (!(node instanceof IStartNode))
- ((AbstractBasicBlock) node).addIncoming(prev);
- if (prev instanceof IExitNode) {
+ if (prev instanceof IExitNode || prev == null) {
dead.add(node);
+ return;
} else if (prev instanceof AbstractBasicBlock) {
((AbstractBasicBlock) prev).addOutgoing(node);
}
+ if (!(node instanceof IStartNode))
+ ((AbstractBasicBlock) node).addIncoming(prev);
}
}
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 eec6afd05a1..61e1ccb7fb1 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
@@ -61,8 +61,8 @@ public class CxxNodeFactory extends NodeFactory implements INodeFactory {
* @param caseSt
* @return
*/
- public IBranchNode createLabeledNode(IASTNode caseSt) {
- IBranchNode node = createLabeledNode(caseSt.getRawSignature());
+ public IBranchNode createBranchNode(IASTNode caseSt) {
+ IBranchNode node = createBranchNode(caseSt.getRawSignature());
((AbstractBasicBlock) node).setData(caseSt);
return node;
}
diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java
index e5adb4bfb97..21544c87d09 100644
--- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java
+++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java
@@ -15,9 +15,17 @@ import java.util.Iterator;
import org.eclipse.cdt.codan.core.cxx.internal.model.cfg.ControlFlowGraphBuilder;
import org.eclipse.cdt.codan.core.test.CodanTestCase;
+import org.eclipse.cdt.codan.internal.core.cfg.AbstractBasicBlock;
import org.eclipse.cdt.codan.internal.core.cfg.ControlFlowGraph;
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;
+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.IPlainNode;
+import org.eclipse.cdt.codan.provisional.core.model.cfg.ISingleOutgoing;
+import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
@@ -36,6 +44,7 @@ import org.eclipse.core.runtime.CoreException;
*/
public class ControlFlowGraphTest extends CodanTestCase {
ControlFlowGraph graph;
+
void processFile(IFile file) throws CoreException, InterruptedException {
// create translation unit and access index
ICElement model = CoreModel.getDefault().create(file);
@@ -64,28 +73,30 @@ public class ControlFlowGraphTest extends CodanTestCase {
{
shouldVisitDeclarations = true;
}
+
public int visit(IASTDeclaration decl) {
if (decl instanceof IASTFunctionDefinition) {
- graph = new ControlFlowGraphBuilder().build((IASTFunctionDefinition) decl);
+ graph = new ControlFlowGraphBuilder()
+ .build((IASTFunctionDefinition) decl);
return PROCESS_ABORT;
}
return PROCESS_CONTINUE;
}
};
ast.accept(visitor);
-
}
+
void buildCfg() {
try {
-
- IResource el = cproject.getProject().findMember(currentFile.getName());
+ IResource el = cproject.getProject().findMember(
+ currentFile.getName());
processFile((IFile) el);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
}
-
+
/**
*
*/
@@ -93,28 +104,32 @@ public class ControlFlowGraphTest extends CodanTestCase {
assertNotNull(graph);
assertNotNull(graph.getStartNode());
Collection<IBasicBlock> nodes = graph.getNodes();
- for (Iterator<IBasicBlock> iterator = nodes.iterator(); iterator.hasNext();) {
- IBasicBlock node = iterator.next();
+ for (Iterator<IBasicBlock> iterator = nodes.iterator(); iterator
+ .hasNext();) {
+ IBasicBlock node = iterator.next();
checkNode(node);
}
-
}
+
/**
* @param node
*/
private void checkNode(IBasicBlock node) {
- for (Iterator<IBasicBlock> iterator = node.getIncomingIterator(); iterator.hasNext();) {
+ for (Iterator<IBasicBlock> iterator = node.getIncomingIterator(); iterator
+ .hasNext();) {
IBasicBlock b = iterator.next();
if (!contains(node, b.getOutgoingIterator()))
- fail("Block "+node+" inconsitent prev/next "+b);
+ fail("Block " + node + " inconsitent prev/next " + b);
}
- for (Iterator<IBasicBlock> iterator = node.getOutgoingIterator(); iterator.hasNext();) {
+ for (Iterator<IBasicBlock> iterator = node.getOutgoingIterator(); iterator
+ .hasNext();) {
IBasicBlock b = iterator.next();
if (!contains(node, b.getIncomingIterator()))
- fail("Block "+node+" inconsitent next/prev "+b);
+ fail("Block " + node + " inconsitent next/prev " + b);
}
if (node instanceof IDecisionNode) {
- assertTrue("decision node outgping size",node.getOutgoingSize()>1);
+ assertTrue("decision node outgping size",
+ node.getOutgoingSize() > 1);
assertNotNull(((IDecisionNode) node).getMergeNode());
}
}
@@ -124,15 +139,62 @@ public class ControlFlowGraphTest extends CodanTestCase {
* @param outgoingIterator
* @return
*/
- private boolean contains(IBasicBlock node,
- Iterator<IBasicBlock> iterator) {
+ private boolean contains(IBasicBlock node, Iterator<IBasicBlock> iterator) {
for (; iterator.hasNext();) {
IBasicBlock b = iterator.next();
- if (b.equals(node)) return true;
+ if (b.equals(node))
+ return true;
}
return false;
}
+ /**
+ * @param file
+ */
+ protected void buildAndCheck(String file) {
+ load(file);
+ buildCfg();
+ checkCfg();
+ }
+
+ /**
+ * @param des
+ * @return
+ */
+ private String data(IBasicBlock des) {
+ return ((AbstractBasicBlock) des).toStringData();
+ }
+
+ /**
+ * Return first node after the branch
+ *
+ * @param des
+ * @return
+ */
+ private IBasicBlock branchEnd(IDecisionNode des, String label) {
+ for (Iterator<IBasicBlock> iterator = des.getOutgoingIterator(); iterator
+ .hasNext();) {
+ IBranchNode bn = (IBranchNode) iterator.next();
+ if (label.equals(bn.getLabel()))
+ return bn.getOutgoing();
+ }
+ return null;
+ }
+
+ /**
+ * Return node where control jumps, following the chain until jump is hit
+ *
+ * @param a
+ * @return
+ */
+ private IBasicBlock jumpEnd(IBasicBlock a) {
+ if (a instanceof IJumpNode)
+ return ((IJumpNode) a).getOutgoing();
+ if (a instanceof ISingleOutgoing)
+ return jumpEnd(((ISingleOutgoing) a).getOutgoing());
+ return null;
+ }
+
/*-
<code file="test1.c">
main() {
@@ -141,11 +203,8 @@ public class ControlFlowGraphTest extends CodanTestCase {
}
</code>
*/
- public void test1() {
- load("test1.c");
- buildCfg();
- checkCfg();
-
+ public void test_basic() {
+ buildAndCheck("test1.c");
}
/*-
@@ -159,10 +218,110 @@ public class ControlFlowGraphTest extends CodanTestCase {
</code>
*/
public void test_while() {
- load("test2.c");
- buildCfg();
- checkCfg();
-
+ buildAndCheck("test2.c");
+ IStartNode startNode = graph.getStartNode();
+ IPlainNode decl = (IPlainNode) startNode.getOutgoing();
+ IConnectorNode conn = (IConnectorNode) decl.getOutgoing();
+ IDecisionNode des = (IDecisionNode) conn.getOutgoing();
+ assertEquals("a--", data(des));
+ IPlainNode bThen = (IPlainNode) branchEnd(des, IBranchNode.THEN);
+ assertEquals("a=a-2;", data(bThen));
+ IBasicBlock bElse = branchEnd(des, IBranchNode.ELSE);
+ IBasicBlock m2 = jumpEnd(bThen);
+ IBasicBlock m1 = jumpEnd(bElse);
+ assertSame(conn, m2);
+ IExitNode ret = (IExitNode) ((IConnectorNode) m1).getOutgoing();
}
+ /*-
+ <code file="test3.c">
+ main() {
+ int a=10;
+ if (a--) {
+ a=a-2;
+ }
+ }
+ </code>
+ */
+ public void test_if() {
+ buildAndCheck("test3.c");
+ IStartNode startNode = graph.getStartNode();
+ IPlainNode decl = (IPlainNode) startNode.getOutgoing();
+ IDecisionNode des = (IDecisionNode) decl.getOutgoing();
+ assertEquals("a--", data(des));
+ IPlainNode bThen = (IPlainNode) branchEnd(des, IBranchNode.THEN);
+ assertEquals("a=a-2;", data(bThen));
+ IBasicBlock bElse = branchEnd(des, IBranchNode.ELSE);
+ IBasicBlock m2 = jumpEnd(bThen);
+ IBasicBlock m1 = jumpEnd(bElse);
+ assertSame(m1, m2);
+ }
+
+ /*-
+ <code file="test4.c">
+ main() {
+ int a=10;
+ if (a--) {
+ return;
+ }
+ }
+ </code>
+ */
+ public void test_if_ret() {
+ buildAndCheck("test4.c");
+ IStartNode startNode = graph.getStartNode();
+ IPlainNode decl = (IPlainNode) startNode.getOutgoing();
+ IDecisionNode des = (IDecisionNode) decl.getOutgoing();
+ assertEquals("a--", data(des));
+ IExitNode bThen = (IExitNode) branchEnd(des, IBranchNode.THEN);
+ IBasicBlock bElse = branchEnd(des, IBranchNode.ELSE);
+ IBasicBlock m1 = jumpEnd(bElse);
+ }
+ /*-
+ <code file="test5.c">
+ main() {
+ int a=10;
+ if (a--) {
+ return;
+ a++;
+ }
+ }
+ </code>
+ */
+ public void test_if_dead() {
+ buildAndCheck("test5.c");
+ IStartNode startNode = graph.getStartNode();
+ IPlainNode decl = (IPlainNode) startNode.getOutgoing();
+ IDecisionNode des = (IDecisionNode) decl.getOutgoing();
+ assertEquals("a--", data(des));
+ IExitNode bThen = (IExitNode) branchEnd(des, IBranchNode.THEN);
+ IBasicBlock bElse = branchEnd(des, IBranchNode.ELSE);
+ IBasicBlock m1 = jumpEnd(bElse);
+ assertEquals(1,graph.getUnconnectedNodeSize());
+ }
+ /*-
+ <code file="test_ifif.c">
+ foo() {
+ int a=10, x=5;
+ if (a--) {
+ if (x<0)
+ a++;
+ }
+ }
+ </code>
+ */
+ public void test_ifif() {
+ buildAndCheck("test_ifif.c");
+ IStartNode startNode = graph.getStartNode();
+ IPlainNode decl = (IPlainNode) startNode.getOutgoing();
+ IDecisionNode des = (IDecisionNode) decl.getOutgoing();
+ assertEquals("a--", data(des));
+ IDecisionNode bThen = (IDecisionNode) branchEnd(des, IBranchNode.THEN);
+ assertEquals("x<0", data(bThen));
+ IBasicBlock bElse = branchEnd(des, IBranchNode.ELSE);
+ IBasicBlock m2 = jumpEnd(branchEnd(bThen,IBranchNode.THEN));
+ IBasicBlock m1 = jumpEnd(bElse);
+ IBasicBlock m3 = jumpEnd(m2);
+ assertSame(m1, m3);
+ }
}
diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractBasicBlock.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractBasicBlock.java
index 4c1384ad158..dbd9134d914 100644
--- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractBasicBlock.java
+++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractBasicBlock.java
@@ -44,7 +44,7 @@ public abstract class AbstractBasicBlock implements IBasicBlock {
*/
public String toStringData() {
if (getData() == null)
- return "";
+ return "0x" + Integer.toHexString(System.identityHashCode(this));
return getData().toString();
}
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 78818babda1..3f08c05990a 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
@@ -18,11 +18,11 @@ import java.util.LinkedHashSet;
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.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.IBranchNode;
import org.eclipse.cdt.codan.provisional.core.model.cfg.ISingleOutgoing;
import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
@@ -55,6 +55,11 @@ public class ControlFlowGraph implements IControlFlowGraph {
exitNodes));
}
+ public void setUnconnectedNodes(Collection<IBasicBlock> nodes) {
+ this.deadNodes = Collections
+ .unmodifiableList(new ArrayList<IBasicBlock>(nodes));
+ }
+
/*
* (non-Javadoc)
*
@@ -97,8 +102,7 @@ public class ControlFlowGraph implements IControlFlowGraph {
* getUnconnectedNodeIterator()
*/
public Iterator<IBasicBlock> getUnconnectedNodeIterator() {
- // TODO Auto-generated method stub
- return null;
+ return deadNodes.iterator();
}
/*
@@ -108,8 +112,7 @@ public class ControlFlowGraph implements IControlFlowGraph {
* getUnconnectedNodeSize()
*/
public int getUnconnectedNodeSize() {
- // TODO Auto-generated method stub
- return 0;
+ return deadNodes.size();
}
/*
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 d37832dc826..10e041fe115 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();
- IBranchNode createLabeledNode(String label);
+ IBranchNode createBranchNode(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 f5839296f22..0129e4928fd 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
@@ -101,7 +101,7 @@ public class NodeFactory implements INodeFactory {
return new ExitNode();
}
- public IBranchNode createLabeledNode(String label) {
+ public IBranchNode createBranchNode(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 218004ab9fd..59a1a4644d6 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
@@ -171,12 +171,10 @@ public class ControlFlowGraphView extends ViewPart {
if (obj instanceof AbstractBasicBlock) {
strdata = ((AbstractBasicBlock) obj).toStringData();
}
- if (strdata == null || strdata.length() == 0) {
- if (obj instanceof IConnectorNode) {
- strdata = blockHexLabel(obj);
- } else if (obj instanceof IJumpNode) {
- strdata = blockHexLabel(((IJumpNode) obj).getJumpNode());
- }
+ if (obj instanceof IConnectorNode) {
+ strdata = blockHexLabel(obj) ;
+ } else if (obj instanceof IJumpNode) {
+ strdata = "jump to "+blockHexLabel(((IJumpNode) obj).getJumpNode());
}
return obj.getClass().getSimpleName() + ": " + strdata;
}

Back to the top