1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-22 14:12:10 +02:00

-added switch to cfg

This commit is contained in:
Alena Laskavaia 2010-04-13 02:07:27 +00:00
parent e15c6eccb9
commit c7f45478a9
4 changed files with 260 additions and 95 deletions

View file

@ -12,6 +12,7 @@ package org.eclipse.cdt.codan.core.cxx.internal.model.cfg;
import java.util.ArrayList;
import java.util.Collection;
import org.eclipse.cdt.codan.internal.core.cfg.AbstractBasicBlock;
import org.eclipse.cdt.codan.internal.core.cfg.ConnectorNode;
import org.eclipse.cdt.codan.internal.core.cfg.DecisionNode;
@ -21,8 +22,11 @@ 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.IASTBreakStatement;
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
@ -30,6 +34,7 @@ import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
/**
@ -79,63 +84,138 @@ public class ControlFlowGraphBuilder {
addOutgoing(prev, node);
return node;
} else if (body instanceof IASTIfStatement) {
DecisionNode node = factory.createDecisionNode(
((IASTIfStatement) body).getConditionExpression());
return createIf(prev, (IASTIfStatement) body);
} else if (body instanceof IASTWhileStatement) {
return createWhile(prev, (IASTWhileStatement) body);
} else if (body instanceof IASTForStatement) {
return createFor(prev, (IASTForStatement) body);
} else if (body instanceof IASTReturnStatement) {
CxxExitNode node = factory.createExitNode(body);
node.setStartNode(start);
addOutgoing(prev, node);
return node;
} else if (body instanceof IASTSwitchStatement) {
return createSwitch(prev, (IASTSwitchStatement) body);
}
return prev;
}
/**
* @param prev
* @param body
* @return
*/
protected IBasicBlock createIf(IBasicBlock prev, IASTIfStatement body) {
DecisionNode node = factory.createDecisionNode(body
.getConditionExpression());
addOutgoing(prev, node);
ConnectorNode conn = new ConnectorNode();
node.setConnectorNode(conn);
IBasicBlock els = createSubGraph(node, ((IASTIfStatement) body)
.getElseClause());
IBasicBlock els = createSubGraph(node, body.getElseClause());
conn.addIncoming(els);
addOutgoing(els, conn);
IBasicBlock then = createSubGraph(node, ((IASTIfStatement) body)
.getThenClause());
IBasicBlock then = createSubGraph(node, body.getThenClause());
conn.addIncoming(then);
addOutgoing(then, conn);
return conn;
} else if (body instanceof IASTWhileStatement) {
// add continue connector
IConnectorNode nContinue = factory.createConnectorNode();
addOutgoing(prev, nContinue);
// decision node
CxxDecisionNode decision = factory.createDecisionNode(
((IASTWhileStatement) body).getCondition());
addOutgoing(nContinue, 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,
((IASTWhileStatement) body).getBody());
JumpNode jumpContinue = new JumpNode();
addOutgoing(nBody, jumpContinue);
jumpContinue.setJump(nContinue, true);
// connect with backward link
addOutgoing(jumpContinue, nContinue);
}
return nBreak;
} else if (body instanceof IASTForStatement) {
/**
* @param prev
* @param body
* @return
*/
private IBasicBlock createSwitch(IBasicBlock prev, IASTSwitchStatement body) {
DecisionNode node = factory.createDecisionNode(body
.getControllerExpression());
addOutgoing(prev, node);
ConnectorNode conn = new ConnectorNode();
node.setConnectorNode(conn);
createSwitchBody(node, conn, body.getBody());
return conn;
}
/**
* @param switchNode
* @param conn
* @param def
* @param body
*/
private void createSwitchBody(DecisionNode switchNode, ConnectorNode conn,
IASTStatement body) {
if (!(body instanceof IASTCompoundStatement))
return; // bad
IASTCompoundStatement comp = (IASTCompoundStatement) body;
IASTNode[] children = comp.getChildren();
IBasicBlock prev = switchNode;
int labelNum = 1;
for (int i = 0; i < children.length; i++) {
IASTNode elem = children[i];
if (elem instanceof IASTCaseStatement) {
IASTCaseStatement caseSt = (IASTCaseStatement) elem;
IPlainNode nextSt = factory
.createPlainNode();
if (!(prev instanceof IExitNode) && prev != switchNode)
addOutgoing(prev, nextSt);
switchNode.addOutgoing(new CxxDecisionArc(switchNode, labelNum,
nextSt, caseSt));
labelNum++;
((AbstractBasicBlock)nextSt).addIncoming(switchNode);
prev = nextSt;
continue;
}
if (elem instanceof IASTBreakStatement) {
JumpNode nBreak = (JumpNode) factory.createJumpNode();
addOutgoing(prev, nBreak);
nBreak.setJump(conn, false);
conn.addIncoming(nBreak);
prev = nBreak;
continue;
}
if (elem instanceof IASTDefaultStatement) {
IASTDefaultStatement caseSt = (IASTDefaultStatement) elem;
IPlainNode nextSt = factory
.createPlainNode();
if (!(prev instanceof IExitNode) && prev != switchNode)
addOutgoing(prev, nextSt);
switchNode.addOutgoing(new CxxDecisionArc(switchNode, 0,
nextSt, caseSt));
((AbstractBasicBlock)nextSt).addIncoming(switchNode);
prev = nextSt;
continue;
}
IBasicBlock last = createSubGraph(prev, elem);
prev = last;
}
}
/**
* @param prev
* @param forNode
* @return
*/
private IBasicBlock createFor(IBasicBlock prev, IASTForStatement forNode) {
// add initializer
IPlainNode init = factory.createPlainNode(((IASTForStatement) body).getInitializerStatement());
IPlainNode init = factory.createPlainNode(forNode
.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());
CxxDecisionNode decision = factory.createDecisionNode(forNode
.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());
IBasicBlock nBody = createSubGraph(decision, forNode.getBody());
// inc
IPlainNode inc = factory.createPlainNode(((IASTForStatement) body).getIterationExpression());
IPlainNode inc = factory.createPlainNode(forNode
.getIterationExpression());
addOutgoing(nBody, inc);
JumpNode jumpContinue = new JumpNode();
addOutgoing(inc, jumpContinue);
@ -143,13 +223,33 @@ public class ControlFlowGraphBuilder {
// connect with backward link
addOutgoing(jumpContinue, nContinue2);
return nBreak;
} else if (body instanceof IASTReturnStatement) {
CxxExitNode node = factory.createExitNode(body);
node.setStartNode(start);
addOutgoing(prev, node);
return node;
}
return prev;
/**
* @param prev
* @param body
* @return
*/
protected IBasicBlock createWhile(IBasicBlock prev, IASTWhileStatement body) {
// add continue connector
IConnectorNode nContinue = factory.createConnectorNode();
addOutgoing(prev, nContinue);
// decision node
CxxDecisionNode decision = factory.createDecisionNode(body
.getCondition());
addOutgoing(nContinue, 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, body.getBody());
JumpNode jumpContinue = new JumpNode();
addOutgoing(nBody, jumpContinue);
jumpContinue.setJump(nContinue, true);
// connect with backward link
addOutgoing(jumpContinue, nContinue);
return nBreak;
}
/**

View file

@ -0,0 +1,44 @@
/*******************************************************************************
* 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.DecisionArc;
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 CxxDecisionArc extends DecisionArc {
private IASTNode label;
/**
* @param decisionNode
* @param i
* @param node
*/
public CxxDecisionArc(DecisionNode decisionNode, int i, IBasicBlock node,
IASTNode label) {
super(decisionNode, i, node);
this.label = label;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.codan.internal.core.cfg.DecisionArc#toString()
*/
@Override
public String toString() {
return label.getRawSignature();
}
}

View file

@ -0,0 +1,49 @@
/*******************************************************************************
* 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.cfg;
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionArc;
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
public class DecisionArc implements IDecisionArc {
private final DecisionNode decisionNode;
protected int index;
protected IBasicBlock node;
public DecisionArc(DecisionNode decisionNode, int i, IBasicBlock node) {
this.decisionNode = decisionNode;
this.index = i;
this.node = node;
}
public int getIndex() {
return index;
}
public IBasicBlock getOutgoing() {
return node;
}
public IDecisionNode getDecisionNode() {
return this.decisionNode;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return index + "";
}
}

View file

@ -29,38 +29,6 @@ public class DecisionNode extends AbstractSingleIncomingNode implements
private List<IDecisionArc> next = new ArrayList<IDecisionArc>(2);
private IConnectorNode conn;
class DecisionArc implements IDecisionArc {
int index;
IBasicBlock node;
DecisionArc(int i, IBasicBlock node) {
this.index = i;
this.node = node;
}
public int getIndex() {
return index;
}
public IBasicBlock getOutgoing() {
return node;
}
public IDecisionNode getDecisionNode() {
return DecisionNode.this;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return index + "";
}
}
/**
* @param prev
*/
@ -75,7 +43,11 @@ public class DecisionNode extends AbstractSingleIncomingNode implements
@Override
public void addOutgoing(IBasicBlock node) {
DecisionArc arc = new DecisionArc(getDecisionArcSize(), node);
DecisionArc arc = new DecisionArc(this, getDecisionArcSize(), node);
next.add(arc);
}
public void addOutgoing(IDecisionArc arc) {
next.add(arc);
}