mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
- added node factory and cfg for for statement
This commit is contained in:
parent
21d46e71ee
commit
0908dbf0cd
17 changed files with 318 additions and 119 deletions
|
@ -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.DecisionNode;
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.JumpNode;
|
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.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.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.IASTCompoundStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
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.IASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
@ -36,6 +40,7 @@ public class ControlFlowGraphBuilder {
|
||||||
Collection<IExitNode> exits;
|
Collection<IExitNode> exits;
|
||||||
Collection<IBasicBlock> dead;
|
Collection<IBasicBlock> dead;
|
||||||
CxxExitNode returnExit;
|
CxxExitNode returnExit;
|
||||||
|
CxxNodeFactory factory = new CxxNodeFactory();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param def
|
* @param def
|
||||||
|
@ -48,7 +53,8 @@ public class ControlFlowGraphBuilder {
|
||||||
dead = new ArrayList<IBasicBlock>();
|
dead = new ArrayList<IBasicBlock>();
|
||||||
IBasicBlock last = createSubGraph(start, body);
|
IBasicBlock last = createSubGraph(start, body);
|
||||||
if (!(last instanceof IExitNode)) {
|
if (!(last instanceof IExitNode)) {
|
||||||
returnExit = new CxxExitNode(last, start, null);
|
returnExit = (CxxExitNode) factory.createExitNode(null);
|
||||||
|
returnExit.setStartNode(start);
|
||||||
addOutgoing(last, returnExit);
|
addOutgoing(last, returnExit);
|
||||||
}
|
}
|
||||||
return new CxxControlFlowGraph(start, exits);
|
return new CxxControlFlowGraph(start, exits);
|
||||||
|
@ -69,11 +75,11 @@ public class ControlFlowGraphBuilder {
|
||||||
}
|
}
|
||||||
} else if (body instanceof IASTExpressionStatement
|
} else if (body instanceof IASTExpressionStatement
|
||||||
|| body instanceof IASTDeclarationStatement) {
|
|| body instanceof IASTDeclarationStatement) {
|
||||||
CxxPlainNode node = new CxxPlainNode(prev, body);
|
CxxPlainNode node = factory.createPlainNode(body);
|
||||||
addOutgoing(prev, node);
|
addOutgoing(prev, node);
|
||||||
return node;
|
return node;
|
||||||
} else if (body instanceof IASTIfStatement) {
|
} else if (body instanceof IASTIfStatement) {
|
||||||
DecisionNode node = new CxxDecisionNode(prev,
|
DecisionNode node = factory.createDecisionNode(
|
||||||
((IASTIfStatement) body).getConditionExpression());
|
((IASTIfStatement) body).getConditionExpression());
|
||||||
addOutgoing(prev, node);
|
addOutgoing(prev, node);
|
||||||
ConnectorNode conn = new ConnectorNode();
|
ConnectorNode conn = new ConnectorNode();
|
||||||
|
@ -89,26 +95,57 @@ public class ControlFlowGraphBuilder {
|
||||||
return conn;
|
return conn;
|
||||||
} else if (body instanceof IASTWhileStatement) {
|
} else if (body instanceof IASTWhileStatement) {
|
||||||
// add continue connector
|
// add continue connector
|
||||||
ConnectorNode nContinue = new ConnectorNode(prev);
|
IConnectorNode nContinue = factory.createConnectorNode();
|
||||||
addOutgoing(prev, nContinue);
|
addOutgoing(prev, nContinue);
|
||||||
// decision node
|
// decision node
|
||||||
CxxDecisionNode decision = new CxxDecisionNode(nContinue,
|
CxxDecisionNode decision = factory.createDecisionNode(
|
||||||
((IASTWhileStatement) body).getCondition());
|
((IASTWhileStatement) body).getCondition());
|
||||||
addOutgoing(nContinue, decision);
|
addOutgoing(nContinue, decision);
|
||||||
// add break connector
|
// add break connector
|
||||||
ConnectorNode nBreak = new ConnectorNode(decision);
|
IConnectorNode nBreak = factory.createConnectorNode();
|
||||||
addOutgoing(decision, nBreak);
|
addOutgoing(decision, nBreak);
|
||||||
decision.setConnectorNode(nBreak);
|
decision.setConnectorNode(nBreak);
|
||||||
// create body and jump to continue node
|
// create body and jump to continue node
|
||||||
IBasicBlock nBody = createSubGraph(decision,
|
IBasicBlock nBody = createSubGraph(decision,
|
||||||
((IASTWhileStatement) body).getBody());
|
((IASTWhileStatement) body).getBody());
|
||||||
JumpNode jumpContinue = new JumpNode(nBody, nContinue, true);
|
JumpNode jumpContinue = new JumpNode();
|
||||||
addOutgoing(nBody, jumpContinue);
|
addOutgoing(nBody, jumpContinue);
|
||||||
|
jumpContinue.setJump(nContinue, true);
|
||||||
// connect with backward link
|
// 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;
|
return nBreak;
|
||||||
} else if (body instanceof IASTReturnStatement) {
|
} else if (body instanceof IASTReturnStatement) {
|
||||||
CxxExitNode node = new CxxExitNode(prev, start, body);
|
CxxExitNode node = factory.createExitNode(body);
|
||||||
|
node.setStartNode(start);
|
||||||
addOutgoing(prev, node);
|
addOutgoing(prev, node);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -120,6 +157,8 @@ public class ControlFlowGraphBuilder {
|
||||||
* @param node
|
* @param node
|
||||||
*/
|
*/
|
||||||
private void addOutgoing(IBasicBlock prev, IBasicBlock node) {
|
private void addOutgoing(IBasicBlock prev, IBasicBlock node) {
|
||||||
|
if (!(node instanceof IStartNode))
|
||||||
|
((AbstractBasicBlock) node).addIncoming(prev);
|
||||||
if (prev instanceof IExitNode) {
|
if (prev instanceof IExitNode) {
|
||||||
dead.add(node);
|
dead.add(node);
|
||||||
} else if (prev instanceof AbstractBasicBlock) {
|
} else if (prev instanceof AbstractBasicBlock) {
|
||||||
|
|
|
@ -11,34 +11,15 @@
|
||||||
package org.eclipse.cdt.codan.core.cxx.internal.model.cfg;
|
package org.eclipse.cdt.codan.core.cxx.internal.model.cfg;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.DecisionNode;
|
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;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: add description
|
* TODO: add description
|
||||||
*/
|
*/
|
||||||
public class CxxDecisionNode extends DecisionNode {
|
public class CxxDecisionNode extends DecisionNode {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param prev
|
* @param node
|
||||||
* @param expression
|
* the node to set
|
||||||
*/
|
|
||||||
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
|
|
||||||
*/
|
*/
|
||||||
public void setNode(IASTNode node) {
|
public void setNode(IASTNode node) {
|
||||||
setData(node);
|
setData(node);
|
||||||
|
@ -50,6 +31,7 @@ public class CxxDecisionNode extends DecisionNode {
|
||||||
public IASTNode getNode() {
|
public IASTNode getNode() {
|
||||||
return (IASTNode) getData();
|
return (IASTNode) getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -11,36 +11,13 @@
|
||||||
package org.eclipse.cdt.codan.core.cxx.internal.model.cfg;
|
package org.eclipse.cdt.codan.core.cxx.internal.model.cfg;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.ExitNode;
|
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.IExitNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: add description
|
* TODO: add description
|
||||||
*/
|
*/
|
||||||
public class CxxExitNode extends ExitNode implements IExitNode {
|
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
|
* @param node
|
||||||
* the node to set
|
* the node to set
|
||||||
|
@ -55,12 +32,13 @@ public class CxxExitNode extends ExitNode implements IExitNode {
|
||||||
public IASTNode getNode() {
|
public IASTNode getNode() {
|
||||||
return (IASTNode) getData();
|
return (IASTNode) getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String toStringData() {
|
public String toStringData() {
|
||||||
if (getNode() == null)
|
if (getNode() == null)
|
||||||
return "";
|
return "return; // fake";
|
||||||
return getNode().getRawSignature();
|
return getNode().getRawSignature();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,7 +11,6 @@
|
||||||
package org.eclipse.cdt.codan.core.cxx.internal.model.cfg;
|
package org.eclipse.cdt.codan.core.cxx.internal.model.cfg;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.PlainNode;
|
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;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,24 +20,8 @@ public class CxxPlainNode extends PlainNode {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param prev
|
* @param node
|
||||||
* @param body
|
* the node to set
|
||||||
*/
|
|
||||||
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
|
|
||||||
*/
|
*/
|
||||||
public void setNode(IASTNode node) {
|
public void setNode(IASTNode node) {
|
||||||
setData(node);
|
setData(node);
|
||||||
|
@ -50,6 +33,7 @@ public class CxxPlainNode extends PlainNode {
|
||||||
public IASTNode getNode() {
|
public IASTNode getNode() {
|
||||||
return (IASTNode) getData();
|
return (IASTNode) getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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.core.test.CodanTestCase;
|
||||||
import org.eclipse.cdt.codan.internal.core.cfg.ControlFlowGraph;
|
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.IBasicBlock;
|
||||||
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
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;
|
||||||
|
@ -105,10 +106,17 @@ public class ControlFlowGraphTest extends CodanTestCase {
|
||||||
for (Iterator<IBasicBlock> iterator = node.getIncomingIterator(); iterator.hasNext();) {
|
for (Iterator<IBasicBlock> iterator = node.getIncomingIterator(); iterator.hasNext();) {
|
||||||
IBasicBlock b = iterator.next();
|
IBasicBlock b = iterator.next();
|
||||||
if (!contains(node, b.getOutgoingIterator()))
|
if (!contains(node, b.getOutgoingIterator()))
|
||||||
fail("Block "+node+" inc "+b);
|
fail("Block "+node+" inconsitent prev/next "+b);
|
||||||
|
}
|
||||||
|
for (Iterator<IBasicBlock> 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 {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-
|
||||||
|
<code file="test2.c">
|
||||||
|
main() {
|
||||||
|
int a=10;
|
||||||
|
while (a--) {
|
||||||
|
a=a-2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
*/
|
||||||
|
public void test_while() {
|
||||||
|
load("test2.c");
|
||||||
|
buildCfg();
|
||||||
|
checkCfg();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.eclipse.cdt.codan.internal.core.cfg;
|
package org.eclipse.cdt.codan.internal.core.cfg;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
||||||
|
|
||||||
public abstract class AbstractBasicBlock implements IBasicBlock {
|
public abstract class AbstractBasicBlock implements IBasicBlock {
|
||||||
|
@ -46,4 +47,14 @@ public abstract class AbstractBasicBlock implements IBasicBlock {
|
||||||
return "";
|
return "";
|
||||||
return getData().toString();
|
return getData().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getClass().getSimpleName() + ": " + toStringData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param node
|
||||||
|
*/
|
||||||
|
public abstract void addIncoming(IBasicBlock node);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,10 @@ import org.eclipse.cdt.codan.provisional.core.model.cfg.ISingleIncoming;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractSingleIncomingNode extends AbstractBasicBlock
|
public abstract class AbstractSingleIncomingNode extends AbstractBasicBlock
|
||||||
implements ISingleIncoming {
|
implements ISingleIncoming {
|
||||||
final IBasicBlock prev;
|
private IBasicBlock prev;
|
||||||
|
|
||||||
public AbstractSingleIncomingNode(IBasicBlock prev) {
|
public AbstractSingleIncomingNode() {
|
||||||
super();
|
super();
|
||||||
this.prev = prev;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterator<IBasicBlock> getIncomingIterator() {
|
public Iterator<IBasicBlock> getIncomingIterator() {
|
||||||
|
@ -28,4 +27,13 @@ public abstract class AbstractSingleIncomingNode extends AbstractBasicBlock
|
||||||
public IBasicBlock getIncoming() {
|
public IBasicBlock getIncoming() {
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setIncoming(IBasicBlock prev) {
|
||||||
|
this.prev = prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addIncoming(IBasicBlock node) {
|
||||||
|
setIncoming(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ package org.eclipse.cdt.codan.internal.core.cfg;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IJumpNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IJumpNode;
|
||||||
|
@ -28,11 +27,7 @@ public class ConnectorNode extends AbstractSingleOutgoingNode implements
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConnectorNode(IBasicBlock prev) {
|
@Override
|
||||||
super();
|
|
||||||
addIncoming(prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addIncoming(IBasicBlock node) {
|
public void addIncoming(IBasicBlock node) {
|
||||||
incoming.add(node);
|
incoming.add(node);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IControlFlowGraph;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IControlFlowGraph;
|
||||||
|
|
|
@ -15,6 +15,7 @@ import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionArc;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionArc;
|
||||||
|
@ -63,8 +64,8 @@ public class DecisionNode extends AbstractSingleIncomingNode implements
|
||||||
/**
|
/**
|
||||||
* @param prev
|
* @param prev
|
||||||
*/
|
*/
|
||||||
public DecisionNode(IBasicBlock prev) {
|
public DecisionNode() {
|
||||||
super(prev);
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDecisionArcs(Collection<IDecisionArc> next) {
|
public void setDecisionArcs(Collection<IDecisionArc> next) {
|
||||||
|
|
|
@ -10,18 +10,11 @@ import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
|
||||||
* Plain node has one prev one jump
|
* Plain node has one prev one jump
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ExitNode extends AbstractBasicBlock implements IExitNode {
|
public class ExitNode extends AbstractSingleIncomingNode implements IExitNode {
|
||||||
private IBasicBlock prev;
|
|
||||||
private IStartNode start;
|
private IStartNode start;
|
||||||
|
|
||||||
public ExitNode(IBasicBlock prev, IStartNode start) {
|
public ExitNode() {
|
||||||
super();
|
super();
|
||||||
this.prev = prev;
|
|
||||||
this.start = start;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterator<IBasicBlock> getIncomingIterator() {
|
|
||||||
return new OneElementIterator<IBasicBlock>(prev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -29,26 +22,14 @@ public class ExitNode extends AbstractBasicBlock implements IExitNode {
|
||||||
return Collections.EMPTY_LIST.iterator();
|
return Collections.EMPTY_LIST.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getIncomingSize() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getOutgoingSize() {
|
public int getOutgoingSize() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IBasicBlock getIncoming() {
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IStartNode getStartNode() {
|
public IStartNode getStartNode() {
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIncoming(IBasicBlock prev) {
|
|
||||||
this.prev = prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStartNode(IStartNode start) {
|
public void setStartNode(IStartNode start) {
|
||||||
this.start = start;
|
this.start = start;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,8 @@ public class JumpNode extends AbstractSingleIncomingNode implements IJumpNode {
|
||||||
private IConnectorNode jump;
|
private IConnectorNode jump;
|
||||||
private boolean backward;
|
private boolean backward;
|
||||||
|
|
||||||
public JumpNode(IBasicBlock entry, IConnectorNode jump, boolean backward) {
|
public JumpNode() {
|
||||||
super(entry);
|
super();
|
||||||
this.jump = jump;
|
|
||||||
this.backward = backward;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterator<IBasicBlock> getOutgoingIterator() {
|
public Iterator<IBasicBlock> getOutgoingIterator() {
|
||||||
|
@ -47,11 +45,12 @@ public class JumpNode extends AbstractSingleIncomingNode implements IJumpNode {
|
||||||
return backward;
|
return backward;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setJump(IConnectorNode jump) {
|
public void setJump(IConnectorNode jump, boolean backward) {
|
||||||
if (this.jump != null)
|
if (this.jump != null)
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Cannot modify exiting connector"); //$NON-NLS-1$
|
"Cannot modify exiting connector"); //$NON-NLS-1$
|
||||||
this.jump = jump;
|
this.jump = jump;
|
||||||
|
this.backward = backward;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBackward(boolean backward) {
|
public void setBackward(boolean backward) {
|
||||||
|
@ -60,6 +59,8 @@ public class JumpNode extends AbstractSingleIncomingNode implements IJumpNode {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addOutgoing(IBasicBlock node) {
|
public void addOutgoing(IBasicBlock node) {
|
||||||
|
if (node == jump)
|
||||||
|
return;
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package org.eclipse.cdt.codan.internal.core.cfg;
|
package org.eclipse.cdt.codan.internal.core.cfg;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IPlainNode;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IPlainNode;
|
||||||
|
|
||||||
|
@ -12,9 +11,8 @@ import org.eclipse.cdt.codan.provisional.core.model.cfg.IPlainNode;
|
||||||
public class PlainNode extends AbstractSingleIncomingNode implements IPlainNode {
|
public class PlainNode extends AbstractSingleIncomingNode implements IPlainNode {
|
||||||
IBasicBlock next;
|
IBasicBlock next;
|
||||||
|
|
||||||
public PlainNode(IBasicBlock prev, IBasicBlock next) {
|
public PlainNode() {
|
||||||
super(prev);
|
super();
|
||||||
this.next = next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterator<IBasicBlock> getOutgoingIterator() {
|
public Iterator<IBasicBlock> getOutgoingIterator() {
|
||||||
|
|
|
@ -2,7 +2,6 @@ package org.eclipse.cdt.codan.internal.core.cfg;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
||||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
|
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) {
|
public void addOutgoing(IBasicBlock node) {
|
||||||
setOutgoing(node);
|
setOutgoing(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addIncoming(IBasicBlock node) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue