1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-09-10 03:53:21 +02:00

Clean up interfaces for control flow graph

This commit is contained in:
Alena Laskavaia 2010-05-25 02:16:11 +00:00
parent 6a49ab36dd
commit 3ec7ac60fa
16 changed files with 114 additions and 121 deletions

View file

@ -161,6 +161,8 @@ public class ControlFlowGraphBuilder {
CxxPlainNode node = factory.createPlainNode(body); CxxPlainNode node = factory.createPlainNode(body);
addOutgoing(prev, node); addOutgoing(prev, node);
return node; return node;
} else if (body == null) {
// skip - sometimes body is empty such as no else
} else { } else {
System.err.println("unknown statement for cfg: " + body); //$NON-NLS-1$ System.err.println("unknown statement for cfg: " + body); //$NON-NLS-1$
} }
@ -172,16 +174,24 @@ public class ControlFlowGraphBuilder {
* @return * @return
*/ */
private boolean isThrowStatement(IASTNode body) { private boolean isThrowStatement(IASTNode body) {
if (!(body instanceof IASTExpressionStatement)) return false; if (!(body instanceof IASTExpressionStatement))
IASTExpression expression = ((IASTExpressionStatement) body).getExpression(); return false;
if (!(expression instanceof IASTUnaryExpression)) return false; IASTExpression expression = ((IASTExpressionStatement) body)
.getExpression();
if (!(expression instanceof IASTUnaryExpression))
return false;
return ((IASTUnaryExpression) expression).getOperator() == IASTUnaryExpression.op_throw; return ((IASTUnaryExpression) expression).getOperator() == IASTUnaryExpression.op_throw;
} }
private boolean isExitStatement(IASTNode body) { private boolean isExitStatement(IASTNode body) {
if (!(body instanceof IASTExpressionStatement)) return false; if (!(body instanceof IASTExpressionStatement))
IASTExpression expression = ((IASTExpressionStatement) body).getExpression(); return false;
if (!(expression instanceof IASTFunctionCallExpression)) return false; IASTExpression expression = ((IASTExpressionStatement) body)
IASTExpression functionNameExpression = ((IASTFunctionCallExpression) expression).getFunctionNameExpression(); .getExpression();
if (!(expression instanceof IASTFunctionCallExpression))
return false;
IASTExpression functionNameExpression = ((IASTFunctionCallExpression) expression)
.getFunctionNameExpression();
return functionNameExpression.getRawSignature().equals("exit"); //$NON-NLS-1$ return functionNameExpression.getRawSignature().equals("exit"); //$NON-NLS-1$
} }

View file

@ -14,6 +14,7 @@ import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import org.eclipse.cdt.codan.core.cxx.internal.model.cfg.ControlFlowGraphBuilder; import org.eclipse.cdt.codan.core.cxx.internal.model.cfg.ControlFlowGraphBuilder;
import org.eclipse.cdt.codan.core.model.IChecker;
import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock;
import org.eclipse.cdt.codan.core.model.cfg.IBranchNode; import org.eclipse.cdt.codan.core.model.cfg.IBranchNode;
import org.eclipse.cdt.codan.core.model.cfg.IConnectorNode; import org.eclipse.cdt.codan.core.model.cfg.IConnectorNode;
@ -23,48 +24,21 @@ import org.eclipse.cdt.codan.core.model.cfg.IJumpNode;
import org.eclipse.cdt.codan.core.model.cfg.IPlainNode; import org.eclipse.cdt.codan.core.model.cfg.IPlainNode;
import org.eclipse.cdt.codan.core.model.cfg.ISingleOutgoing; import org.eclipse.cdt.codan.core.model.cfg.ISingleOutgoing;
import org.eclipse.cdt.codan.core.model.cfg.IStartNode; import org.eclipse.cdt.codan.core.model.cfg.IStartNode;
import org.eclipse.cdt.codan.core.test.CodanTestCase; import org.eclipse.cdt.codan.core.test.CodanFastCxxAstTestCase;
import org.eclipse.cdt.codan.internal.core.cfg.AbstractBasicBlock; import org.eclipse.cdt.codan.internal.core.cfg.AbstractBasicBlock;
import org.eclipse.cdt.codan.internal.core.cfg.ControlFlowGraph; import org.eclipse.cdt.codan.internal.core.cfg.ControlFlowGraph;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.c.CASTVisitor; import org.eclipse.cdt.core.dom.ast.c.CASTVisitor;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
/** /**
* TODO: add description * TODO: add description
*/ */
public class ControlFlowGraphTest extends CodanTestCase { public class ControlFlowGraphTest extends CodanFastCxxAstTestCase {
ControlFlowGraph graph; ControlFlowGraph graph;
void processFile(IFile file) throws CoreException, InterruptedException {
// create translation unit and access index
ICElement model = CoreModel.getDefault().create(file);
if (!(model instanceof ITranslationUnit))
return; // not a C/C++ file
ITranslationUnit tu = (ITranslationUnit) model;
IIndex index = CCorePlugin.getIndexManager().getIndex(tu.getCProject());
// lock the index for read access
index.acquireReadLock();
try {
// create index based ast
IASTTranslationUnit ast = tu.getAST(index,
ITranslationUnit.AST_SKIP_INDEXED_HEADERS);
// traverse the ast using the visitor pattern.
processAst(ast);
} finally {
index.releaseReadLock();
}
}
/** /**
* @param ast * @param ast
*/ */
@ -74,6 +48,7 @@ public class ControlFlowGraphTest extends CodanTestCase {
shouldVisitDeclarations = true; shouldVisitDeclarations = true;
} }
@Override
public int visit(IASTDeclaration decl) { public int visit(IASTDeclaration decl) {
if (decl instanceof IASTFunctionDefinition) { if (decl instanceof IASTFunctionDefinition) {
graph = new ControlFlowGraphBuilder() graph = new ControlFlowGraphBuilder()
@ -86,17 +61,6 @@ public class ControlFlowGraphTest extends CodanTestCase {
ast.accept(visitor); ast.accept(visitor);
} }
void buildCfg() {
try {
IResource el = cproject.getProject().findMember(
currentFile.getName());
processFile((IFile) el);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
}
/** /**
* *
*/ */
@ -115,16 +79,16 @@ public class ControlFlowGraphTest extends CodanTestCase {
* @param node * @param node
*/ */
private void checkNode(IBasicBlock node) { private void checkNode(IBasicBlock node) {
for (Iterator<IBasicBlock> iterator = node.getIncomingIterator(); iterator IBasicBlock[] incomingNodes = node.getIncomingNodes();
.hasNext();) { for (int i = 0; i < incomingNodes.length; i++) {
IBasicBlock b = iterator.next(); IBasicBlock b = incomingNodes[i];
if (!contains(node, b.getOutgoingIterator())) if (!contains(node, b.getOutgoingNodes()))
fail("Block " + node + " inconsitent prev/next " + b); fail("Block " + node + " inconsitent prev/next " + b);
} }
for (Iterator<IBasicBlock> iterator = node.getOutgoingIterator(); iterator IBasicBlock[] outgoingNodes = node.getOutgoingNodes();
.hasNext();) { for (int i = 0; i < outgoingNodes.length; i++) {
IBasicBlock b = iterator.next(); IBasicBlock b = outgoingNodes[i];
if (!contains(node, b.getIncomingIterator())) if (!contains(node, b.getIncomingNodes()))
fail("Block " + node + " inconsitent next/prev " + b); fail("Block " + node + " inconsitent next/prev " + b);
} }
if (node instanceof IDecisionNode) { if (node instanceof IDecisionNode) {
@ -139,9 +103,9 @@ public class ControlFlowGraphTest extends CodanTestCase {
* @param outgoingIterator * @param outgoingIterator
* @return * @return
*/ */
private boolean contains(IBasicBlock node, Iterator<IBasicBlock> iterator) { private boolean contains(IBasicBlock node, IBasicBlock[] blocks) {
for (; iterator.hasNext();) { for (int i = 0; i < blocks.length; i++) {
IBasicBlock b = iterator.next(); IBasicBlock b = blocks[i];
if (b.equals(node)) if (b.equals(node))
return true; return true;
} }
@ -151,18 +115,28 @@ public class ControlFlowGraphTest extends CodanTestCase {
protected void buildAndCheck(String code) { protected void buildAndCheck(String code) {
buildAndCheck(code, false); buildAndCheck(code, false);
} }
protected void buildAndCheck_cpp(String code) { protected void buildAndCheck_cpp(String code) {
buildAndCheck(code, true); buildAndCheck(code, true);
} }
/** /**
* @param file * @param file
*/ */
protected void buildAndCheck(String code, boolean cpp) { protected void buildAndCheck(String code, boolean cpp) {
loadcode(code, cpp); buildCfg(code, cpp);
buildCfg();
checkCfg(); checkCfg();
} }
/**
* @param code
* @param cpp
*/
private void buildCfg(String code, boolean cpp) {
parse(code, cpp ? ParserLanguage.CPP : ParserLanguage.C, true);
processAst(tu);
}
/** /**
* @param des * @param des
* @return * @return
@ -178,9 +152,10 @@ public class ControlFlowGraphTest extends CodanTestCase {
* @return * @return
*/ */
private IBasicBlock branchEnd(IDecisionNode des, String label) { private IBasicBlock branchEnd(IDecisionNode des, String label) {
for (Iterator<IBasicBlock> iterator = des.getOutgoingIterator(); iterator IBasicBlock[] outgoingNodes = des.getOutgoingNodes();
.hasNext();) { for (int i = 0; i < outgoingNodes.length; i++) {
IBranchNode bn = (IBranchNode) iterator.next(); IBasicBlock iBasicBlock = outgoingNodes[i];
IBranchNode bn = (IBranchNode) iBasicBlock;
if (label.equals(bn.getLabel())) if (label.equals(bn.getLabel()))
return bn.getOutgoing(); return bn.getOutgoing();
} }
@ -273,6 +248,17 @@ public class ControlFlowGraphTest extends CodanTestCase {
IBasicBlock m1 = jumpEnd(bElse); IBasicBlock m1 = jumpEnd(bElse);
} }
// main() {
// return;
// a++;
// }
public void test_dead() {
buildCfg(getAboveComment(), false);
IStartNode startNode = graph.getStartNode();
IExitNode ret = (IExitNode) startNode.getOutgoing();
assertEquals(1, graph.getUnconnectedNodeSize());
}
// main() { // main() {
// int a=10; // int a=10;
// if (a--) { // if (a--) {
@ -281,7 +267,7 @@ public class ControlFlowGraphTest extends CodanTestCase {
// } // }
// } // }
public void test_if_dead() { public void test_if_dead() {
buildAndCheck(getAboveComment()); buildCfg(getAboveComment(), false);
IStartNode startNode = graph.getStartNode(); IStartNode startNode = graph.getStartNode();
IPlainNode decl = (IPlainNode) startNode.getOutgoing(); IPlainNode decl = (IPlainNode) startNode.getOutgoing();
IDecisionNode des = (IDecisionNode) decl.getOutgoing(); IDecisionNode des = (IDecisionNode) decl.getOutgoing();
@ -337,4 +323,14 @@ public class ControlFlowGraphTest extends CodanTestCase {
IExitNode exit = exitNodeIterator.next(); IExitNode exit = exitNodeIterator.next();
assertEquals("exit(0);", data(exit)); assertEquals("exit(0);", data(exit));
} }
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.codan.core.test.CodanFastCxxAstTestCase#getChecker()
*/
@Override
public IChecker getChecker() {
return null;
}
} }

View file

@ -48,7 +48,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
*/ */
@SuppressWarnings("restriction") @SuppressWarnings("restriction")
public abstract class CodanFastCxxAstTestCase extends TestCase { public abstract class CodanFastCxxAstTestCase extends TestCase {
IASTTranslationUnit tu; protected IASTTranslationUnit tu;
protected String getAboveComment() { protected String getAboveComment() {
return getContents(1)[0].toString(); return getContents(1)[0].toString();
@ -118,6 +118,7 @@ public abstract class CodanFastCxxAstTestCase extends TestCase {
assertEquals(problems.length, 0); assertEquals(problems.length, 0);
} }
} }
this.tu = tu;
return tu; return tu;
} }

View file

@ -14,6 +14,7 @@ package org.eclipse.cdt.codan.core.test;
import junit.framework.Test; import junit.framework.Test;
import junit.framework.TestSuite; import junit.framework.TestSuite;
import org.eclipse.cdt.codan.core.cfg.ControlFlowGraphTest;
import org.eclipse.cdt.codan.core.cxx.CxxAstUtilsTest; import org.eclipse.cdt.codan.core.cxx.CxxAstUtilsTest;
import org.eclipse.cdt.codan.core.param.BasicProblemPreferenceTest; import org.eclipse.cdt.codan.core.param.BasicProblemPreferenceTest;
import org.eclipse.cdt.codan.core.param.ListProblemPreferenceTest; import org.eclipse.cdt.codan.core.param.ListProblemPreferenceTest;
@ -41,6 +42,7 @@ public class CodanFastTestSuite extends TestSuite {
suite.addTestSuite(ListProblemPreferenceTest.class); suite.addTestSuite(ListProblemPreferenceTest.class);
suite.addTestSuite(MapProblemPreferenceTest.class); suite.addTestSuite(MapProblemPreferenceTest.class);
suite.addTestSuite(CxxAstUtilsTest.class); suite.addTestSuite(CxxAstUtilsTest.class);
suite.addTestSuite(ControlFlowGraphTest.class);
return suite; return suite;
} }
} }

View file

@ -1,6 +1,5 @@
package org.eclipse.cdt.codan.core.model.cfg; package org.eclipse.cdt.codan.core.model.cfg;
import java.util.Iterator;
/** /**
* *
@ -12,9 +11,9 @@ import java.util.Iterator;
* <li>{@link I} * <li>{@link I}
*/ */
public interface IBasicBlock { public interface IBasicBlock {
Iterator<IBasicBlock> getIncomingIterator(); IBasicBlock[] getIncomingNodes();
Iterator<IBasicBlock> getOutgoingIterator(); IBasicBlock[] getOutgoingNodes();
int getIncomingSize(); int getIncomingSize();

View file

@ -6,17 +6,24 @@ import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock;
import org.eclipse.cdt.codan.core.model.cfg.ICfgData; import org.eclipse.cdt.codan.core.model.cfg.ICfgData;
public abstract class AbstractBasicBlock implements IBasicBlock, ICfgData { public abstract class AbstractBasicBlock implements IBasicBlock, ICfgData {
public final static IBasicBlock[] EMPTY_LIST = new IBasicBlock[0];
private Object data; private Object data;
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see org.eclipse.cdt.codan.internal.core.cfg.ICfgData#getData() * @see org.eclipse.cdt.codan.internal.core.cfg.ICfgData#getData()
*/ */
public Object getData() { public Object getData() {
return data; return data;
} }
/* (non-Javadoc) /*
* @see org.eclipse.cdt.codan.internal.core.cfg.ICfgData#setData(java.lang.Object) * (non-Javadoc)
*
* @see
* org.eclipse.cdt.codan.internal.core.cfg.ICfgData#setData(java.lang.Object
* )
*/ */
public void setData(Object data) { public void setData(Object data) {
this.data = data; this.data = data;

View file

@ -1,7 +1,5 @@
package org.eclipse.cdt.codan.internal.core.cfg; package org.eclipse.cdt.codan.internal.core.cfg;
import java.util.Iterator;
import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock;
import org.eclipse.cdt.codan.core.model.cfg.ISingleIncoming; import org.eclipse.cdt.codan.core.model.cfg.ISingleIncoming;
@ -17,8 +15,8 @@ public abstract class AbstractSingleIncomingNode extends AbstractBasicBlock
super(); super();
} }
public Iterator<IBasicBlock> getIncomingIterator() { public IBasicBlock[] getIncomingNodes() {
return new OneElementIterator<IBasicBlock>(prev); return new IBasicBlock[] { prev };
} }
public int getIncomingSize() { public int getIncomingSize() {

View file

@ -1,7 +1,5 @@
package org.eclipse.cdt.codan.internal.core.cfg; package org.eclipse.cdt.codan.internal.core.cfg;
import java.util.Iterator;
import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock;
import org.eclipse.cdt.codan.core.model.cfg.ISingleOutgoing; import org.eclipse.cdt.codan.core.model.cfg.ISingleOutgoing;
@ -17,8 +15,8 @@ public abstract class AbstractSingleOutgoingNode extends AbstractBasicBlock
super(); super();
} }
public Iterator<IBasicBlock> getOutgoingIterator() { public IBasicBlock[] getOutgoingNodes() {
return new OneElementIterator<IBasicBlock>(next); return new IBasicBlock[] { next };
} }
public int getOutgoingSize() { public int getOutgoingSize() {

View file

@ -11,7 +11,6 @@
package org.eclipse.cdt.codan.internal.core.cfg; package org.eclipse.cdt.codan.internal.core.cfg;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock;
import org.eclipse.cdt.codan.core.model.cfg.IConnectorNode; import org.eclipse.cdt.codan.core.model.cfg.IConnectorNode;
@ -39,8 +38,8 @@ public class ConnectorNode extends AbstractSingleOutgoingNode implements
* @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock# * @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock#
* getIncomingIterator() * getIncomingIterator()
*/ */
public Iterator<IBasicBlock> getIncomingIterator() { public IBasicBlock[] getIncomingNodes() {
return incoming.iterator(); return incoming.toArray(new IBasicBlock[incoming.size()]);
} }
/* /*

View file

@ -79,10 +79,9 @@ public class ControlFlowGraph implements IControlFlowGraph {
+ ((AbstractBasicBlock) node).toStringData()); + ((AbstractBasicBlock) node).toStringData());
if (node instanceof IDecisionNode) { if (node instanceof IDecisionNode) {
// todo // todo
Iterator<IBasicBlock> branches = ((IDecisionNode) node) IBasicBlock[] branches = ((IDecisionNode) node).getOutgoingNodes();
.getOutgoingIterator(); for (int i = 0; i < branches.length; i++) {
for (; branches.hasNext();) { IBasicBlock brNode = branches[i];
IBasicBlock brNode = branches.next();
System.out.println("{"); //$NON-NLS-1$ System.out.println("{"); //$NON-NLS-1$
print(brNode); print(brNode);
System.out.println("}"); //$NON-NLS-1$ System.out.println("}"); //$NON-NLS-1$
@ -139,9 +138,9 @@ public class ControlFlowGraph implements IControlFlowGraph {
if (result.contains(start)) if (result.contains(start))
return; return;
result.add(start); result.add(start);
for (Iterator<IBasicBlock> outgoingIterator = start IBasicBlock[] outgoingNodes = start.getOutgoingNodes();
.getOutgoingIterator(); outgoingIterator.hasNext();) { for (int i = 0; i < outgoingNodes.length; i++) {
IBasicBlock b = outgoingIterator.next(); IBasicBlock b = outgoingNodes[i];
getNodes(b, result); getNodes(b, result);
} }
} }

View file

@ -11,7 +11,6 @@
package org.eclipse.cdt.codan.internal.core.cfg; package org.eclipse.cdt.codan.internal.core.cfg;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import java.util.List;
import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock;
@ -46,8 +45,8 @@ public class DecisionNode extends AbstractSingleIncomingNode implements
* @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock# * @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock#
* getOutgoingIterator() * getOutgoingIterator()
*/ */
public Iterator<IBasicBlock> getOutgoingIterator() { public IBasicBlock[] getOutgoingNodes() {
return next.iterator(); return next.toArray(new IBasicBlock[next.size()]);
} }
/* /*

View file

@ -1,8 +1,5 @@
package org.eclipse.cdt.codan.internal.core.cfg; package org.eclipse.cdt.codan.internal.core.cfg;
import java.util.Collections;
import java.util.Iterator;
import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock;
import org.eclipse.cdt.codan.core.model.cfg.IExitNode; import org.eclipse.cdt.codan.core.model.cfg.IExitNode;
import org.eclipse.cdt.codan.core.model.cfg.IStartNode; import org.eclipse.cdt.codan.core.model.cfg.IStartNode;
@ -18,9 +15,8 @@ public class ExitNode extends AbstractSingleIncomingNode implements IExitNode {
super(); super();
} }
@SuppressWarnings("unchecked") public IBasicBlock[] getOutgoingNodes() {
public Iterator<IBasicBlock> getOutgoingIterator() { return EMPTY_LIST;
return Collections.EMPTY_LIST.iterator();
} }
public int getOutgoingSize() { public int getOutgoingSize() {

View file

@ -1,7 +1,5 @@
package org.eclipse.cdt.codan.internal.core.cfg; package org.eclipse.cdt.codan.internal.core.cfg;
import java.util.Iterator;
import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock;
import org.eclipse.cdt.codan.core.model.cfg.IConnectorNode; import org.eclipse.cdt.codan.core.model.cfg.IConnectorNode;
import org.eclipse.cdt.codan.core.model.cfg.IJumpNode; import org.eclipse.cdt.codan.core.model.cfg.IJumpNode;
@ -19,8 +17,8 @@ public class JumpNode extends AbstractSingleIncomingNode implements IJumpNode {
super(); super();
} }
public Iterator<IBasicBlock> getOutgoingIterator() { public IBasicBlock[] getOutgoingNodes() {
return new OneElementIterator<IBasicBlock>(jump); return new IBasicBlock[] { jump };
} }
public int getOutgoingSize() { public int getOutgoingSize() {

View file

@ -1,7 +1,5 @@
package org.eclipse.cdt.codan.internal.core.cfg; package org.eclipse.cdt.codan.internal.core.cfg;
import java.util.Iterator;
import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock;
import org.eclipse.cdt.codan.core.model.cfg.IPlainNode; import org.eclipse.cdt.codan.core.model.cfg.IPlainNode;
@ -16,8 +14,8 @@ public class PlainNode extends AbstractSingleIncomingNode implements IPlainNode
super(); super();
} }
public Iterator<IBasicBlock> getOutgoingIterator() { public IBasicBlock[] getOutgoingNodes() {
return new OneElementIterator<IBasicBlock>(next); return new IBasicBlock[] { next };
} }
public int getOutgoingSize() { public int getOutgoingSize() {

View file

@ -1,8 +1,5 @@
package org.eclipse.cdt.codan.internal.core.cfg; package org.eclipse.cdt.codan.internal.core.cfg;
import java.util.Collections;
import java.util.Iterator;
import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock;
import org.eclipse.cdt.codan.core.model.cfg.IStartNode; import org.eclipse.cdt.codan.core.model.cfg.IStartNode;
@ -15,9 +12,8 @@ public class StartNode extends AbstractSingleOutgoingNode implements IStartNode
super(); super();
} }
@SuppressWarnings("unchecked") public IBasicBlock[] getIncomingNodes() {
public Iterator<IBasicBlock> getIncomingIterator() { return EMPTY_LIST;
return Collections.EMPTY_LIST.iterator();
} }
public int getIncomingSize() { public int getIncomingSize() {

View file

@ -2,7 +2,6 @@ package org.eclipse.cdt.codan.ui.cfgview.views;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator;
import org.eclipse.cdt.codan.core.cxx.internal.model.cfg.ControlFlowGraphBuilder; import org.eclipse.cdt.codan.core.cxx.internal.model.cfg.ControlFlowGraphBuilder;
import org.eclipse.cdt.codan.core.cxx.internal.model.cfg.CxxControlFlowGraph; import org.eclipse.cdt.codan.core.cxx.internal.model.cfg.CxxControlFlowGraph;
@ -122,14 +121,12 @@ public class ControlFlowGraphView extends ViewPart {
return blocks.toArray(); return blocks.toArray();
} else if (parent instanceof IDecisionNode) { } else if (parent instanceof IDecisionNode) {
ArrayList blocks = new ArrayList(); ArrayList blocks = new ArrayList();
Iterator<IBasicBlock> iter = ((IDecisionNode) parent) IBasicBlock[] outgoingNodes = ((IDecisionNode) parent)
.getOutgoingIterator(); .getOutgoingNodes();
if (iter.hasNext()) { for (int i = 0; i < outgoingNodes.length; i++) {
for (; iter.hasNext();) { IBasicBlock arc= outgoingNodes[i];
IBasicBlock arc = iter.next();
blocks.add(arc); blocks.add(arc);
} }
}
blocks.add(((IDecisionNode) parent).getMergeNode()); blocks.add(((IDecisionNode) parent).getMergeNode());
return blocks.toArray(); return blocks.toArray();
} else if (parent instanceof IBranchNode) { } else if (parent instanceof IBranchNode) {