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 884c1a9a7cb..9fb9923788a 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 @@ -17,10 +17,14 @@ 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.JumpNode; 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.IPlainNode; +import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement; 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.IASTIfStatement; import org.eclipse.cdt.core.dom.ast.IASTNode; @@ -36,6 +40,7 @@ public class ControlFlowGraphBuilder { Collection exits; Collection dead; CxxExitNode returnExit; + CxxNodeFactory factory = new CxxNodeFactory(); /** * @param def @@ -48,7 +53,8 @@ public class ControlFlowGraphBuilder { dead = new ArrayList(); IBasicBlock last = createSubGraph(start, body); if (!(last instanceof IExitNode)) { - returnExit = new CxxExitNode(last, start, null); + returnExit = (CxxExitNode) factory.createExitNode(null); + returnExit.setStartNode(start); addOutgoing(last, returnExit); } return new CxxControlFlowGraph(start, exits); @@ -69,11 +75,11 @@ public class ControlFlowGraphBuilder { } } else if (body instanceof IASTExpressionStatement || body instanceof IASTDeclarationStatement) { - CxxPlainNode node = new CxxPlainNode(prev, body); + CxxPlainNode node = factory.createPlainNode(body); addOutgoing(prev, node); return node; } else if (body instanceof IASTIfStatement) { - DecisionNode node = new CxxDecisionNode(prev, + DecisionNode node = factory.createDecisionNode( ((IASTIfStatement) body).getConditionExpression()); addOutgoing(prev, node); ConnectorNode conn = new ConnectorNode(); @@ -89,26 +95,57 @@ public class ControlFlowGraphBuilder { return conn; } else if (body instanceof IASTWhileStatement) { // add continue connector - ConnectorNode nContinue = new ConnectorNode(prev); + IConnectorNode nContinue = factory.createConnectorNode(); addOutgoing(prev, nContinue); // decision node - CxxDecisionNode decision = new CxxDecisionNode(nContinue, + CxxDecisionNode decision = factory.createDecisionNode( ((IASTWhileStatement) body).getCondition()); addOutgoing(nContinue, decision); // add break connector - ConnectorNode nBreak = new ConnectorNode(decision); + IConnectorNode nBreak = factory.createConnectorNode(); addOutgoing(decision, nBreak); decision.setConnectorNode(nBreak); // create body and jump to continue node IBasicBlock nBody = createSubGraph(decision, ((IASTWhileStatement) body).getBody()); - JumpNode jumpContinue = new JumpNode(nBody, nContinue, true); + JumpNode jumpContinue = new JumpNode(); addOutgoing(nBody, jumpContinue); + jumpContinue.setJump(nContinue, true); // connect with backward link - nContinue.addIncoming(jumpContinue); + addOutgoing(jumpContinue, nContinue); + + return nBreak; + } else if (body instanceof IASTForStatement) { + // add initializer + IPlainNode init = factory.createPlainNode(((IASTForStatement) body).getInitializerStatement()); + addOutgoing(prev, init); + prev = init; + // add continue connector + IConnectorNode nContinue2 = factory.createConnectorNode(); + addOutgoing(prev, nContinue2); + // decision node + CxxDecisionNode decision = factory.createDecisionNode( + ((IASTForStatement) body).getConditionExpression()); + addOutgoing(nContinue2, decision); + // add break connector + IConnectorNode nBreak = factory.createConnectorNode(); + addOutgoing(decision, nBreak); + decision.setConnectorNode(nBreak); + // create body and jump to continue node + IBasicBlock nBody = createSubGraph(decision, + ((IASTForStatement) body).getBody()); + // inc + IPlainNode inc = factory.createPlainNode(((IASTForStatement) body).getIterationExpression()); + addOutgoing(nBody, inc); + JumpNode jumpContinue = new JumpNode(); + addOutgoing(inc, jumpContinue); + jumpContinue.setJump(nContinue2, true); + // connect with backward link + addOutgoing(jumpContinue, nContinue2); return nBreak; } else if (body instanceof IASTReturnStatement) { - CxxExitNode node = new CxxExitNode(prev, start, body); + CxxExitNode node = factory.createExitNode(body); + node.setStartNode(start); addOutgoing(prev, node); return node; } @@ -120,6 +157,8 @@ public class ControlFlowGraphBuilder { * @param node */ private void addOutgoing(IBasicBlock prev, IBasicBlock node) { + if (!(node instanceof IStartNode)) + ((AbstractBasicBlock) node).addIncoming(prev); if (prev instanceof IExitNode) { dead.add(node); } else if (prev instanceof AbstractBasicBlock) { diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxDecisionNode.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxDecisionNode.java index d6aafa304e0..8f9a725c1c6 100644 --- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxDecisionNode.java +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxDecisionNode.java @@ -11,34 +11,15 @@ package org.eclipse.cdt.codan.core.cxx.internal.model.cfg; import org.eclipse.cdt.codan.internal.core.cfg.DecisionNode; -import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock; import org.eclipse.cdt.core.dom.ast.IASTNode; /** * TODO: add description */ public class CxxDecisionNode extends DecisionNode { - - /** - * @param prev - * @param expression - */ - public CxxDecisionNode(IBasicBlock prev, IASTNode expression) { - super(prev); - this.setNode(expression); - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return getNode().getRawSignature(); - } - - /** - * @param node the node to set + * @param node + * the node to set */ public void setNode(IASTNode node) { setData(node); @@ -50,6 +31,7 @@ public class CxxDecisionNode extends DecisionNode { public IASTNode getNode() { return (IASTNode) getData(); } + /** * @return */ diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxExitNode.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxExitNode.java index 5a4c5562d64..44005e773bf 100644 --- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxExitNode.java +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxExitNode.java @@ -11,36 +11,13 @@ package org.eclipse.cdt.codan.core.cxx.internal.model.cfg; import org.eclipse.cdt.codan.internal.core.cfg.ExitNode; -import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock; import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode; -import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode; import org.eclipse.cdt.core.dom.ast.IASTNode; /** * TODO: add description */ public class CxxExitNode extends ExitNode implements IExitNode { - /** - * @param prev - * @param start - */ - public CxxExitNode(IBasicBlock prev, IStartNode start, IASTNode node) { - super(prev, start); - setNode(node); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - if (getNode()!=null) - return getNode().getRawSignature(); - return "return; // fake"; - } - /** * @param node * the node to set @@ -55,12 +32,13 @@ public class CxxExitNode extends ExitNode implements IExitNode { public IASTNode getNode() { return (IASTNode) getData(); } + /** * @return */ public String toStringData() { if (getNode() == null) - return ""; + return "return; // fake"; return getNode().getRawSignature(); } } 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 new file mode 100644 index 00000000000..f19c1c98414 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxNodeFactory.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2009 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +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.model.NodeFactory; +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.INodeFactory; +import org.eclipse.cdt.codan.provisional.core.model.cfg.IPlainNode; +import org.eclipse.cdt.core.dom.ast.IASTNode; + +/** + * TODO: add description + */ +public class CxxNodeFactory extends NodeFactory implements INodeFactory { + public CxxNodeFactory() { + super(); + } + + public IPlainNode createPlainNode() { + return new CxxPlainNode(); + } + + public IDecisionNode createDecisionNode() { + return new CxxDecisionNode(); + } + + public IExitNode createExitNode() { + return new CxxExitNode(); + } + public CxxPlainNode createPlainNode(IASTNode ast) { + IPlainNode node = createPlainNode(); + ((AbstractBasicBlock) node).setData(ast); + return (CxxPlainNode) node; + } + + public CxxDecisionNode createDecisionNode(IASTNode ast) { + IDecisionNode node = createDecisionNode(); + ((AbstractBasicBlock) node).setData(ast); + return (CxxDecisionNode) node; + } + public CxxExitNode createExitNode(IASTNode ast) { + IExitNode node = createExitNode(); + ((AbstractBasicBlock) node).setData(ast); + return (CxxExitNode) node; + } +} diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxPlainNode.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxPlainNode.java index 8cef5c65c3b..37fdf8b1abc 100644 --- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxPlainNode.java +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/CxxPlainNode.java @@ -11,7 +11,6 @@ package org.eclipse.cdt.codan.core.cxx.internal.model.cfg; import org.eclipse.cdt.codan.internal.core.cfg.PlainNode; -import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock; import org.eclipse.cdt.core.dom.ast.IASTNode; /** @@ -21,24 +20,8 @@ public class CxxPlainNode extends PlainNode { /** - * @param prev - * @param body - */ - public CxxPlainNode(IBasicBlock prev, IASTNode body) { - super(prev, null); - this.setNode(body); - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return getNode().getRawSignature(); - } - - /** - * @param node the node to set + * @param node + * the node to set */ public void setNode(IASTNode node) { setData(node); @@ -50,6 +33,7 @@ public class CxxPlainNode extends PlainNode { public IASTNode getNode() { return (IASTNode) getData(); } + /** * @return */ 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 31cad4226ef..a1c0bbbe3ef 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 @@ -17,6 +17,7 @@ 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.ControlFlowGraph; import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock; +import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; @@ -105,10 +106,17 @@ public class ControlFlowGraphTest extends CodanTestCase { for (Iterator iterator = node.getIncomingIterator(); iterator.hasNext();) { IBasicBlock b = iterator.next(); if (!contains(node, b.getOutgoingIterator())) - fail("Block "+node+" inc "+b); + fail("Block "+node+" inconsitent prev/next "+b); + } + for (Iterator iterator = node.getOutgoingIterator(); iterator.hasNext();) { + IBasicBlock b = iterator.next(); + if (!contains(node, b.getIncomingIterator())) + fail("Block "+node+" inconsitent next/prev "+b); + } + if (node instanceof IDecisionNode) { + assertTrue("decision node outgping size",node.getOutgoingSize()>1); + assertNotNull(((IDecisionNode) node).getConnectionNode()); } - // TODO Auto-generated method stub - } /** @@ -140,5 +148,21 @@ public class ControlFlowGraphTest extends CodanTestCase { } + /*- + + main() { + int a=10; + while (a--) { + a=a-2; + } + } + + */ + public void test_while() { + load("test2.c"); + buildCfg(); + checkCfg(); + + } } 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 4ffa7a97fc6..4c1384ad158 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 @@ -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; public abstract class AbstractBasicBlock implements IBasicBlock { @@ -46,4 +47,14 @@ public abstract class AbstractBasicBlock implements IBasicBlock { return ""; return getData().toString(); } + + @Override + public String toString() { + return getClass().getSimpleName() + ": " + toStringData(); + } + + /** + * @param node + */ + public abstract void addIncoming(IBasicBlock node); } diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractSingleIncomingNode.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractSingleIncomingNode.java index a11d8bb20d2..b8948fdfead 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractSingleIncomingNode.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractSingleIncomingNode.java @@ -10,11 +10,10 @@ import org.eclipse.cdt.codan.provisional.core.model.cfg.ISingleIncoming; */ public abstract class AbstractSingleIncomingNode extends AbstractBasicBlock implements ISingleIncoming { - final IBasicBlock prev; + private IBasicBlock prev; - public AbstractSingleIncomingNode(IBasicBlock prev) { + public AbstractSingleIncomingNode() { super(); - this.prev = prev; } public Iterator getIncomingIterator() { @@ -28,4 +27,13 @@ public abstract class AbstractSingleIncomingNode extends AbstractBasicBlock public IBasicBlock getIncoming() { return prev; } + + public void setIncoming(IBasicBlock prev) { + this.prev = prev; + } + + @Override + public void addIncoming(IBasicBlock node) { + setIncoming(node); + } } diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ConnectorNode.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ConnectorNode.java index e60dd1c8ed7..5c6301e7010 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ConnectorNode.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ConnectorNode.java @@ -12,7 +12,6 @@ package org.eclipse.cdt.codan.internal.core.cfg; import java.util.ArrayList; import java.util.Iterator; - 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.IJumpNode; @@ -28,11 +27,7 @@ public class ConnectorNode extends AbstractSingleOutgoingNode implements super(); } - public ConnectorNode(IBasicBlock prev) { - super(); - addIncoming(prev); - } - + @Override public void addIncoming(IBasicBlock node) { incoming.add(node); } 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 c140b430c79..8077938e32c 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 @@ -16,7 +16,6 @@ import java.util.Collections; import java.util.Iterator; 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.IConnectorNode; import org.eclipse.cdt.codan.provisional.core.model.cfg.IControlFlowGraph; 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 cf315cab2bf..2e8d5a3b800 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.Collection; import java.util.Collections; 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.IConnectorNode; import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionArc; @@ -63,8 +64,8 @@ public class DecisionNode extends AbstractSingleIncomingNode implements /** * @param prev */ - public DecisionNode(IBasicBlock prev) { - super(prev); + public DecisionNode() { + super(); } public void setDecisionArcs(Collection next) { diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ExitNode.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ExitNode.java index 76ed3247104..db4aef7714b 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ExitNode.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ExitNode.java @@ -10,18 +10,11 @@ import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode; * Plain node has one prev one jump * */ -public class ExitNode extends AbstractBasicBlock implements IExitNode { - private IBasicBlock prev; +public class ExitNode extends AbstractSingleIncomingNode implements IExitNode { private IStartNode start; - public ExitNode(IBasicBlock prev, IStartNode start) { + public ExitNode() { super(); - this.prev = prev; - this.start = start; - } - - public Iterator getIncomingIterator() { - return new OneElementIterator(prev); } @SuppressWarnings("unchecked") @@ -29,26 +22,14 @@ public class ExitNode extends AbstractBasicBlock implements IExitNode { return Collections.EMPTY_LIST.iterator(); } - public int getIncomingSize() { - return 1; - } - public int getOutgoingSize() { return 0; } - public IBasicBlock getIncoming() { - return prev; - } - public IStartNode getStartNode() { return start; } - public void setIncoming(IBasicBlock prev) { - this.prev = prev; - } - public void setStartNode(IStartNode start) { this.start = start; } diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/JumpNode.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/JumpNode.java index a88ec7d3f48..eddaf38bcd1 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/JumpNode.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/JumpNode.java @@ -15,10 +15,8 @@ public class JumpNode extends AbstractSingleIncomingNode implements IJumpNode { private IConnectorNode jump; private boolean backward; - public JumpNode(IBasicBlock entry, IConnectorNode jump, boolean backward) { - super(entry); - this.jump = jump; - this.backward = backward; + public JumpNode() { + super(); } public Iterator getOutgoingIterator() { @@ -47,11 +45,12 @@ public class JumpNode extends AbstractSingleIncomingNode implements IJumpNode { return backward; } - public void setJump(IConnectorNode jump) { + public void setJump(IConnectorNode jump, boolean backward) { if (this.jump != null) throw new IllegalArgumentException( "Cannot modify exiting connector"); //$NON-NLS-1$ this.jump = jump; + this.backward = backward; } public void setBackward(boolean backward) { @@ -60,6 +59,8 @@ public class JumpNode extends AbstractSingleIncomingNode implements IJumpNode { @Override public void addOutgoing(IBasicBlock node) { + if (node == jump) + return; throw new UnsupportedOperationException(); } } 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 89f56f558c3..6e25c51ad4a 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,7 +1,6 @@ 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; @@ -12,9 +11,8 @@ import org.eclipse.cdt.codan.provisional.core.model.cfg.IPlainNode; public class PlainNode extends AbstractSingleIncomingNode implements IPlainNode { IBasicBlock next; - public PlainNode(IBasicBlock prev, IBasicBlock next) { - super(prev); - this.next = next; + public PlainNode() { + super(); } public Iterator getOutgoingIterator() { diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/StartNode.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/StartNode.java index 3fad0f08841..19dd968f125 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/StartNode.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/StartNode.java @@ -2,7 +2,6 @@ package org.eclipse.cdt.codan.internal.core.cfg; import java.util.Collections; import java.util.Iterator; - import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock; import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode; @@ -28,4 +27,9 @@ public class StartNode extends AbstractSingleOutgoingNode implements IStartNode public void addOutgoing(IBasicBlock node) { setOutgoing(node); } + + @Override + public void addIncoming(IBasicBlock node) { + throw new UnsupportedOperationException(); + } } diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/NodeFactory.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/NodeFactory.java new file mode 100644 index 00000000000..627acb66c80 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/NodeFactory.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2009 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core.model; + +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.PlainNode; +import org.eclipse.cdt.codan.internal.core.cfg.StartNode; +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.IJumpNode; +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.IStartNode; + +/** + * TODO: add description + */ +public class NodeFactory implements INodeFactory { + IControlFlowGraph graph; + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.INodeFactory# + * getControlFlowGraph() + */ + public IControlFlowGraph getControlFlowGraph() { + return graph; + } + + public NodeFactory() { + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.cdt.codan.provisional.core.model.cfg.INodeFactory#createPlainNode + * () + */ + public IPlainNode createPlainNode() { + return new PlainNode(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.cdt.codan.provisional.core.model.cfg.INodeFactory#createJumpNode + * () + */ + public IJumpNode createJumpNode() { + return new JumpNode(); + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.INodeFactory# + * createDecisionNode() + */ + public IDecisionNode createDecisionNode() { + return new DecisionNode(); + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.INodeFactory# + * createConnectiorNode() + */ + public IConnectorNode createConnectorNode() { + return new ConnectorNode(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.cdt.codan.provisional.core.model.cfg.INodeFactory#createStartNode + * () + */ + public IStartNode createStartNode() { + return new StartNode(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.cdt.codan.provisional.core.model.cfg.INodeFactory#createExitNode + * () + */ + public IExitNode createExitNode() { + return new ExitNode(); + } +} 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 new file mode 100644 index 00000000000..fa19b849982 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/provisional/core/model/cfg/INodeFactory.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2009 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.provisional.core.model.cfg; + +/** + * Control Flow Graph Node factory + */ +public interface INodeFactory { + IPlainNode createPlainNode(); + + IJumpNode createJumpNode(); + + IDecisionNode createDecisionNode(); + + IConnectorNode createConnectorNode(); + + IStartNode createStartNode(); + + IExitNode createExitNode(); +}