mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 01:15:29 +02:00
- added control flow graph - initial commit
This commit is contained in:
parent
6b922df8c2
commit
62c9bdecc9
31 changed files with 1360 additions and 343 deletions
|
@ -11,6 +11,7 @@ Require-Bundle: org.eclipse.core.runtime,
|
|||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: org.eclipse.cdt.codan.core.cxx,
|
||||
org.eclipse.cdt.codan.core.cxx.internal.model;x-friends:="org.eclipse.cdt.codan.checkers.ui,org.eclipse.cdt.codan.ui,org.eclipse.cdt.codan.ui.cxx",
|
||||
org.eclipse.cdt.codan.core.cxx.internal.model.cfg;x-friends:="org.eclipse.cdt.codan.core.test",
|
||||
org.eclipse.cdt.codan.core.cxx.model
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Bundle-Vendor: Eclipse CDT
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/*******************************************************************************
|
||||
* 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 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;
|
||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode;
|
||||
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.IASTFunctionDefinition;
|
||||
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;
|
||||
|
||||
/**
|
||||
* TODO: add description
|
||||
*/
|
||||
public class ControlFlowGraphBuilder {
|
||||
CxxStartNode start;
|
||||
Collection<IExitNode> exits;
|
||||
Collection<IBasicBlock> dead;
|
||||
CxxExitNode returnExit;
|
||||
|
||||
/**
|
||||
* @param def
|
||||
* @return
|
||||
*/
|
||||
public CxxControlFlowGraph build(IASTFunctionDefinition def) {
|
||||
IASTStatement body = def.getBody();
|
||||
start = new CxxStartNode(null);
|
||||
exits = new ArrayList<IExitNode>();
|
||||
dead = new ArrayList<IBasicBlock>();
|
||||
IBasicBlock last = createSubGraph(start, body);
|
||||
if (!(last instanceof IExitNode)) {
|
||||
returnExit = new CxxExitNode(last, start, null);
|
||||
addOutgoing(last, returnExit);
|
||||
}
|
||||
return new CxxControlFlowGraph(start, exits);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param start2
|
||||
* @param body
|
||||
*/
|
||||
private IBasicBlock createSubGraph(IBasicBlock prev, IASTNode body) {
|
||||
if (body instanceof IASTCompoundStatement) {
|
||||
IASTCompoundStatement comp = (IASTCompoundStatement) body;
|
||||
IASTNode[] children = comp.getChildren();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
IASTNode node = children[i];
|
||||
IBasicBlock last = createSubGraph(prev, node);
|
||||
prev = last;
|
||||
}
|
||||
} else if (body instanceof IASTExpressionStatement
|
||||
|| body instanceof IASTDeclarationStatement) {
|
||||
CxxPlainNode node = new CxxPlainNode(prev, body);
|
||||
addOutgoing(prev, node);
|
||||
return node;
|
||||
} else if (body instanceof IASTIfStatement) {
|
||||
DecisionNode node = new DecisionNode(prev);
|
||||
addOutgoing(prev, node);
|
||||
ConnectorNode conn = new ConnectorNode();
|
||||
node.setConnectorNode(conn);
|
||||
IBasicBlock els = createSubGraph(node, ((IASTIfStatement) body)
|
||||
.getElseClause());
|
||||
conn.addIncoming(els);
|
||||
addOutgoing(els, conn);
|
||||
IBasicBlock then = createSubGraph(node, ((IASTIfStatement) body)
|
||||
.getThenClause());
|
||||
conn.addIncoming(then);
|
||||
addOutgoing(then, conn);
|
||||
return conn;
|
||||
} else if (body instanceof IASTReturnStatement) {
|
||||
CxxExitNode node = new CxxExitNode(prev, start, body);
|
||||
addOutgoing(prev, node);
|
||||
return node;
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param prev
|
||||
* @param node
|
||||
*/
|
||||
private void addOutgoing(IBasicBlock prev, IBasicBlock node) {
|
||||
if (prev instanceof IExitNode) {
|
||||
dead.add(node);
|
||||
} else if (prev instanceof AbstractBasicBlock) {
|
||||
((AbstractBasicBlock) prev).addOutgoing(node);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*******************************************************************************
|
||||
* 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 java.util.Collection;
|
||||
|
||||
import org.eclipse.cdt.codan.internal.core.cfg.ControlFlowGraph;
|
||||
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.IASTFunctionDefinition;
|
||||
|
||||
/**
|
||||
* TODO: add description
|
||||
*/
|
||||
public class CxxControlFlowGraph extends ControlFlowGraph {
|
||||
/**
|
||||
* @param start
|
||||
* @param exitNodes
|
||||
*/
|
||||
public CxxControlFlowGraph(IStartNode start, Collection<IExitNode> exitNodes) {
|
||||
super(start, exitNodes);
|
||||
}
|
||||
|
||||
public static CxxControlFlowGraph build(IASTFunctionDefinition def) {
|
||||
return new ControlFlowGraphBuilder().build(def);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
// TODO Auto-generated method stub
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*******************************************************************************
|
||||
* 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.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
|
||||
*/
|
||||
public void setNode(IASTNode node) {
|
||||
setData(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the node
|
||||
*/
|
||||
public IASTNode getNode() {
|
||||
return (IASTNode) getData();
|
||||
}
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String toStringData() {
|
||||
if (getNode() == null)
|
||||
return "";
|
||||
return getNode().getRawSignature();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*******************************************************************************
|
||||
* 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.PlainNode;
|
||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
|
||||
/**
|
||||
* TODO: add description
|
||||
*/
|
||||
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
|
||||
*/
|
||||
public void setNode(IASTNode node) {
|
||||
setData(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the node
|
||||
*/
|
||||
public IASTNode getNode() {
|
||||
return (IASTNode) getData();
|
||||
}
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String toStringData() {
|
||||
if (getNode() == null)
|
||||
return "";
|
||||
return getNode().getRawSignature();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*******************************************************************************
|
||||
* 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.StartNode;
|
||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
||||
|
||||
/**
|
||||
* TODO: add description
|
||||
*/
|
||||
public class CxxStartNode extends StartNode {
|
||||
|
||||
/**
|
||||
* @param next
|
||||
*/
|
||||
public CxxStartNode(IBasicBlock next) {
|
||||
super(next);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "start";
|
||||
}
|
||||
}
|
|
@ -10,7 +10,8 @@ Require-Bundle: org.eclipse.core.runtime,
|
|||
org.eclipse.core.resources;bundle-version="3.5.0",
|
||||
org.eclipse.cdt.core.tests,
|
||||
org.junit;bundle-version="3.8.2",
|
||||
org.eclipse.cdt.codan.core;bundle-version="1.0.0"
|
||||
org.eclipse.cdt.codan.core;bundle-version="1.0.0",
|
||||
org.eclipse.cdt.codan.core.cxx;bundle-version="1.0.0"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Bundle-Vendor: Eclipse CDT
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/*******************************************************************************
|
||||
* 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.cfg;
|
||||
|
||||
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.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.c.CASTVisitor;
|
||||
import org.eclipse.cdt.core.index.IIndex;
|
||||
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;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
|
||||
/**
|
||||
* TODO: add description
|
||||
*/
|
||||
public class ControlFlowGraphTest extends CodanTestCase {
|
||||
ControlFlowGraph graph;
|
||||
void processFile(IFile file) throws CoreException, InterruptedException {
|
||||
// create translation unit and access index
|
||||
ICElement model = CoreModel.getDefault().create(file);
|
||||
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
|
||||
*/
|
||||
private void processAst(IASTTranslationUnit ast) {
|
||||
CASTVisitor visitor = new CASTVisitor() {
|
||||
{
|
||||
shouldVisitDeclarations = true;
|
||||
}
|
||||
public int visit(IASTDeclaration decl) {
|
||||
if (decl instanceof IASTFunctionDefinition) {
|
||||
graph = new ControlFlowGraphBuilder().build((IASTFunctionDefinition) decl);
|
||||
return PROCESS_ABORT;
|
||||
}
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
};
|
||||
ast.accept(visitor);
|
||||
|
||||
}
|
||||
void buildCfg() {
|
||||
try {
|
||||
Path path = new Path(currentFile.toString());
|
||||
IResource el = cproject.getProject().findMember(currentFile.getName());
|
||||
processFile((IFile) el);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
/*-
|
||||
<code file="test1.c">
|
||||
main() {
|
||||
int a;
|
||||
a=1;
|
||||
}
|
||||
</code>
|
||||
*/
|
||||
public void test1() {
|
||||
load("test1.c");
|
||||
buildCfg();
|
||||
graph.print(graph.getStartNode());
|
||||
}
|
||||
}
|
|
@ -10,208 +10,20 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.core.test;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.cdt.codan.core.CodanRuntime;
|
||||
import org.eclipse.cdt.codan.core.model.IProblemReporter;
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.IPDOMManager;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.testplugin.CProjectHelper;
|
||||
import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IWorkspace;
|
||||
import org.eclipse.core.resources.IWorkspaceRunnable;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
|
||||
/**
|
||||
* @author Alena
|
||||
*
|
||||
*/
|
||||
public class CheckerTestCase extends BaseTestCase {
|
||||
ArrayList<File> tempFiles = new ArrayList<File>();
|
||||
protected File tmpDir;
|
||||
private ICProject cproject;
|
||||
public class CheckerTestCase extends CodanTestCase {
|
||||
private IMarker[] markers;
|
||||
private File currentFile;
|
||||
|
||||
/**
|
||||
* Override for c++
|
||||
*
|
||||
* @return is c++ tests
|
||||
*/
|
||||
public boolean isCpp() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
removeLeftOverProjects();
|
||||
cproject = createProject(isCpp());
|
||||
tmpDir = cproject.getProject().getLocation().makeAbsolute().toFile();
|
||||
}
|
||||
|
||||
public File load(String file) {
|
||||
CodanCoreTestActivator plugin = CodanCoreTestActivator.getDefault();
|
||||
String name = getClass().getName();
|
||||
String classFile = name.replaceAll("\\.", "/");
|
||||
classFile += ".java";
|
||||
InputStream st = null;
|
||||
File f = null;
|
||||
try {
|
||||
if (plugin != null) {
|
||||
URL resource = plugin.getBundle().getResource(
|
||||
"src/" + classFile);
|
||||
st = resource.openStream();
|
||||
} else {
|
||||
st = getClass().getResourceAsStream(classFile);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
fail("Cannot find java file: " + classFile);
|
||||
}
|
||||
try {
|
||||
f = saveFile(st, file);
|
||||
st.close();
|
||||
currentFile = f;
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return f;
|
||||
}
|
||||
static final Pattern filePattern = Pattern.compile("file=\"(.*)\"");
|
||||
|
||||
/**
|
||||
* @param st
|
||||
* @param file
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private File saveFile(InputStream st, String file) throws IOException {
|
||||
BufferedReader r = new BufferedReader(new InputStreamReader(st));
|
||||
String line;
|
||||
File testFile = new File(tmpDir, file);
|
||||
tempFiles.add(testFile);
|
||||
PrintStream wr = new PrintStream(testFile);
|
||||
try {
|
||||
boolean print = false;
|
||||
while ((line = r.readLine()) != null) {
|
||||
if (line.contains("<code ")) {
|
||||
Matcher m = filePattern.matcher(line);
|
||||
if (m.find()) {
|
||||
String userFile = m.group(1);
|
||||
if (userFile.equals(file)) {
|
||||
print = true;
|
||||
}
|
||||
}
|
||||
} else if (line.contains("</code>")) {
|
||||
print = false;
|
||||
} else if (print) {
|
||||
wr.println(line);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
wr.close();
|
||||
}
|
||||
return testFile;
|
||||
}
|
||||
|
||||
public void tearDown() throws CoreException {
|
||||
if (cproject != null) {
|
||||
try {
|
||||
cproject.getProject().delete(
|
||||
IResource.FORCE
|
||||
| IResource.ALWAYS_DELETE_PROJECT_CONTENT,
|
||||
new NullProgressMonitor());
|
||||
} catch (CoreException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws CoreException
|
||||
*/
|
||||
private void removeLeftOverProjects() throws CoreException {
|
||||
final IWorkspace workspace = ResourcesPlugin.getWorkspace();
|
||||
IProject[] projects = workspace.getRoot().getProjects();
|
||||
for (int i = 0; i < projects.length; i++) {
|
||||
IProject p = projects[i];
|
||||
if (p.getName().startsWith("Codan")) {
|
||||
p.delete(IResource.FORCE
|
||||
| IResource.ALWAYS_DELETE_PROJECT_CONTENT,
|
||||
new NullProgressMonitor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ICProject createProject(final boolean cpp) throws CoreException {
|
||||
final ICProject cprojects[] = new ICProject[1];
|
||||
ModelJoiner mj = new ModelJoiner();
|
||||
try {
|
||||
// Create the cproject
|
||||
final String projectName = "CodanProjTest_"
|
||||
+ System.currentTimeMillis();
|
||||
final IWorkspace workspace = ResourcesPlugin.getWorkspace();
|
||||
workspace.run(new IWorkspaceRunnable() {
|
||||
public void run(IProgressMonitor monitor) throws CoreException {
|
||||
// Create the cproject
|
||||
ICProject cproject = cpp ? CProjectHelper.createCCProject(
|
||||
projectName, null, IPDOMManager.ID_NO_INDEXER)
|
||||
: CProjectHelper.createCProject(projectName, null,
|
||||
IPDOMManager.ID_NO_INDEXER);
|
||||
cprojects[0] = cproject;
|
||||
}
|
||||
}, null);
|
||||
mj.join();
|
||||
// Index the cproject
|
||||
CCorePlugin.getIndexManager().setIndexerId(cprojects[0],
|
||||
IPDOMManager.ID_FAST_INDEXER);
|
||||
// wait until the indexer is done
|
||||
assertTrue(CCorePlugin.getIndexManager().joinIndexer(360000,
|
||||
new NullProgressMonitor()));
|
||||
} finally {
|
||||
mj.dispose();
|
||||
}
|
||||
return cprojects[0];
|
||||
}
|
||||
|
||||
protected void loadFiles() throws CoreException {
|
||||
ModelJoiner mj = new ModelJoiner();
|
||||
try {
|
||||
final IWorkspace workspace = ResourcesPlugin.getWorkspace();
|
||||
workspace.run(new IWorkspaceRunnable() {
|
||||
public void run(IProgressMonitor monitor) throws CoreException {
|
||||
cproject.getProject().refreshLocal(1, monitor);
|
||||
}
|
||||
}, null);
|
||||
mj.join();
|
||||
// Index the cproject
|
||||
CCorePlugin.getIndexManager().setIndexerId(cproject,
|
||||
IPDOMManager.ID_FAST_INDEXER);
|
||||
// wait until the indexer is done
|
||||
assertTrue(CCorePlugin.getIndexManager().joinIndexer(360000,
|
||||
new NullProgressMonitor()));
|
||||
} finally {
|
||||
mj.dispose();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param i
|
||||
|
@ -243,31 +55,6 @@ public class CheckerTestCase extends BaseTestCase {
|
|||
assertTrue("Error on line " + i + " not found ", found);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pos
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private int pos2line(int pos) throws IOException {
|
||||
FileInputStream st = new FileInputStream(currentFile);
|
||||
try {
|
||||
int c;
|
||||
int line = 1;
|
||||
int cur = 0;
|
||||
while ((c = st.read()) != -1) {
|
||||
if (c == '\n')
|
||||
line++;
|
||||
if (cur >= pos)
|
||||
return line;
|
||||
cur++;
|
||||
}
|
||||
;
|
||||
} finally {
|
||||
st.close();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void checkNoErrors() {
|
||||
assertTrue("Found errors but should not", markers == null
|
||||
|| markers.length == 0);
|
||||
|
|
|
@ -0,0 +1,205 @@
|
|||
/*******************************************************************************
|
||||
* 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.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.IPDOMManager;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.testplugin.CProjectHelper;
|
||||
import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IWorkspace;
|
||||
import org.eclipse.core.resources.IWorkspaceRunnable;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
|
||||
/**
|
||||
* TODO: add description
|
||||
*/
|
||||
public class CodanTestCase extends BaseTestCase {
|
||||
ArrayList<File> tempFiles = new ArrayList<File>();
|
||||
protected File tmpDir;
|
||||
protected ICProject cproject;
|
||||
protected File currentFile;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public CodanTestCase() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
*/
|
||||
public CodanTestCase(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override for c++
|
||||
*
|
||||
* @return is c++ tests
|
||||
*/
|
||||
public boolean isCpp() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
removeLeftOverProjects();
|
||||
cproject = createProject(isCpp());
|
||||
tmpDir = cproject.getProject().getLocation().makeAbsolute().toFile();
|
||||
}
|
||||
|
||||
public File load(String file) {
|
||||
Class clazz = getClass();
|
||||
InputStream st = null;
|
||||
try {
|
||||
st = TestUtils.getJavaFileText(clazz);
|
||||
} catch (IOException e) {
|
||||
fail("Cannot find java file: " + clazz + ": " + e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
File testFile = new File(tmpDir, file);
|
||||
tempFiles.add(testFile);
|
||||
TestUtils.saveFile(st, testFile);
|
||||
st.close();
|
||||
currentFile = testFile;
|
||||
try {
|
||||
cproject.getProject().refreshLocal(1, null);
|
||||
} catch (CoreException e) {
|
||||
// hmm
|
||||
}
|
||||
return testFile;
|
||||
} catch (IOException e) {
|
||||
fail("Cannot save test: " + file + ": " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void tearDown() throws CoreException {
|
||||
if (cproject != null) {
|
||||
try {
|
||||
cproject.getProject().delete(
|
||||
IResource.FORCE
|
||||
| IResource.ALWAYS_DELETE_PROJECT_CONTENT,
|
||||
new NullProgressMonitor());
|
||||
} catch (CoreException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws CoreException
|
||||
*/
|
||||
private void removeLeftOverProjects() throws CoreException {
|
||||
final IWorkspace workspace = ResourcesPlugin.getWorkspace();
|
||||
IProject[] projects = workspace.getRoot().getProjects();
|
||||
for (int i = 0; i < projects.length; i++) {
|
||||
IProject p = projects[i];
|
||||
if (p.getName().startsWith("Codan")) {
|
||||
p.delete(IResource.FORCE
|
||||
| IResource.ALWAYS_DELETE_PROJECT_CONTENT,
|
||||
new NullProgressMonitor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ICProject createProject(final boolean cpp) throws CoreException {
|
||||
final ICProject cprojects[] = new ICProject[1];
|
||||
ModelJoiner mj = new ModelJoiner();
|
||||
try {
|
||||
// Create the cproject
|
||||
final String projectName = "CodanProjTest_"
|
||||
+ System.currentTimeMillis();
|
||||
final IWorkspace workspace = ResourcesPlugin.getWorkspace();
|
||||
workspace.run(new IWorkspaceRunnable() {
|
||||
public void run(IProgressMonitor monitor) throws CoreException {
|
||||
// Create the cproject
|
||||
ICProject cproject = cpp ? CProjectHelper.createCCProject(
|
||||
projectName, null, IPDOMManager.ID_NO_INDEXER)
|
||||
: CProjectHelper.createCProject(projectName, null,
|
||||
IPDOMManager.ID_NO_INDEXER);
|
||||
cprojects[0] = cproject;
|
||||
}
|
||||
}, null);
|
||||
mj.join();
|
||||
// Index the cproject
|
||||
CCorePlugin.getIndexManager().setIndexerId(cprojects[0],
|
||||
IPDOMManager.ID_FAST_INDEXER);
|
||||
// wait until the indexer is done
|
||||
assertTrue(CCorePlugin.getIndexManager().joinIndexer(360000,
|
||||
new NullProgressMonitor()));
|
||||
} finally {
|
||||
mj.dispose();
|
||||
}
|
||||
return cprojects[0];
|
||||
}
|
||||
|
||||
protected void loadFiles() throws CoreException {
|
||||
ModelJoiner mj = new ModelJoiner();
|
||||
try {
|
||||
final IWorkspace workspace = ResourcesPlugin.getWorkspace();
|
||||
workspace.run(new IWorkspaceRunnable() {
|
||||
public void run(IProgressMonitor monitor) throws CoreException {
|
||||
cproject.getProject().refreshLocal(1, monitor);
|
||||
}
|
||||
}, null);
|
||||
mj.join();
|
||||
// Index the cproject
|
||||
CCorePlugin.getIndexManager().setIndexerId(cproject,
|
||||
IPDOMManager.ID_FAST_INDEXER);
|
||||
// wait until the indexer is done
|
||||
assertTrue(CCorePlugin.getIndexManager().joinIndexer(360000,
|
||||
new NullProgressMonitor()));
|
||||
} finally {
|
||||
mj.dispose();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pos
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
protected int pos2line(int pos) throws IOException {
|
||||
FileInputStream st = new FileInputStream(currentFile);
|
||||
try {
|
||||
int c;
|
||||
int line = 1;
|
||||
int cur = 0;
|
||||
while ((c = st.read()) != -1) {
|
||||
if (c == '\n')
|
||||
line++;
|
||||
if (cur >= pos)
|
||||
return line;
|
||||
cur++;
|
||||
}
|
||||
;
|
||||
} finally {
|
||||
st.close();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*******************************************************************************
|
||||
* 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.test;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintStream;
|
||||
import java.net.URL;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* TODO: add description
|
||||
*/
|
||||
public class TestUtils {
|
||||
static final Pattern filePattern = Pattern.compile("file=\"(.*)\"");
|
||||
/**
|
||||
* @param st
|
||||
* @param testFile
|
||||
* @return
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static File saveFile(InputStream st, File testFile)
|
||||
throws FileNotFoundException, IOException {
|
||||
BufferedReader r = new BufferedReader(new InputStreamReader(st));
|
||||
String line;
|
||||
PrintStream wr = new PrintStream(testFile);
|
||||
try {
|
||||
boolean print = false;
|
||||
while ((line = r.readLine()) != null) {
|
||||
if (line.contains("<code ")) {
|
||||
Matcher m = filePattern.matcher(line);
|
||||
if (m.find()) {
|
||||
String userFile = m.group(1);
|
||||
if (userFile.equals(testFile.getName())) {
|
||||
print = true;
|
||||
}
|
||||
}
|
||||
} else if (line.contains("</code>")) {
|
||||
print = false;
|
||||
} else if (print) {
|
||||
wr.println(line);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
wr.close();
|
||||
}
|
||||
return testFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clazz
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static InputStream getJavaFileText(Class clazz) throws IOException {
|
||||
CodanCoreTestActivator plugin = CodanCoreTestActivator.getDefault();
|
||||
String classFile = clazz.getName().replaceAll("\\.", "/");
|
||||
classFile += ".java";
|
||||
InputStream st = null;
|
||||
|
||||
if (plugin != null) {
|
||||
URL resource = plugin.getBundle().getResource(
|
||||
"src/" + classFile);
|
||||
st = resource.openStream();
|
||||
} else {
|
||||
st = clazz.getResourceAsStream(classFile);
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
}
|
|
@ -16,4 +16,6 @@ Export-Package: org.eclipse.cdt.codan.core,
|
|||
org.eclipse.cdt.codan.core.cxx,
|
||||
org.eclipse.cdt.codan.core.test,
|
||||
org.eclipse.cdt.codan.ui",
|
||||
org.eclipse.cdt.codan.internal.core.model;x-friends:="org.eclipse.cdt.codan.core.cxx,org.eclipse.cdt.codan.core.test,org.eclipse.cdt.codan.ui"
|
||||
org.eclipse.cdt.codan.internal.core.cfg;x-friends:="org.eclipse.cdt.codan.core.cxx",
|
||||
org.eclipse.cdt.codan.internal.core.model;x-friends:="org.eclipse.cdt.codan.core.cxx,org.eclipse.cdt.codan.core.test,org.eclipse.cdt.codan.ui",
|
||||
org.eclipse.cdt.codan.provisional.core.model.cfg
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
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 AbstarctBasicBlock implements IBasicBlock {
|
||||
static class OneElementIterator<T> implements Iterator<T> {
|
||||
private T o;
|
||||
|
||||
public OneElementIterator(T o) {
|
||||
this.o = o;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return o != null;
|
||||
}
|
||||
|
||||
public T next() {
|
||||
T x = o;
|
||||
o = null;
|
||||
return x;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
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 {
|
||||
private Object data;
|
||||
|
||||
public Object getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(Object data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
static class OneElementIterator<V> implements Iterator<V> {
|
||||
private V o;
|
||||
|
||||
public OneElementIterator(V o) {
|
||||
this.o = o;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return o != null;
|
||||
}
|
||||
|
||||
public V next() {
|
||||
V x = o;
|
||||
o = null;
|
||||
return x;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void addOutgoing(IBasicBlock node);
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String toStringData() {
|
||||
if (getData() == null)
|
||||
return "";
|
||||
return getData().toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
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.ISingleIncoming;
|
||||
|
||||
/**
|
||||
* Abstrat node with one incoming arc
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractSingleIncomingNode extends AbstractBasicBlock
|
||||
implements ISingleIncoming {
|
||||
final IBasicBlock prev;
|
||||
|
||||
public AbstractSingleIncomingNode(IBasicBlock prev) {
|
||||
super();
|
||||
this.prev = prev;
|
||||
}
|
||||
|
||||
public Iterator<IBasicBlock> getIncomingIterator() {
|
||||
return new OneElementIterator<IBasicBlock>(prev);
|
||||
}
|
||||
|
||||
public int getIncomingSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public IBasicBlock getIncoming() {
|
||||
return prev;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
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.ISingleOutgoing;
|
||||
|
||||
/**
|
||||
* Abstract impl of basic block with single outgoing arc
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractSingleOutgoingNode extends AbstractBasicBlock
|
||||
implements ISingleOutgoing {
|
||||
private IBasicBlock next;
|
||||
|
||||
public AbstractSingleOutgoingNode(IBasicBlock next) {
|
||||
super();
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public Iterator<IBasicBlock> getOutgoingIterator() {
|
||||
return new OneElementIterator<IBasicBlock>(next);
|
||||
}
|
||||
|
||||
public int getOutgoingSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public IBasicBlock getOutgoing() {
|
||||
return next;
|
||||
}
|
||||
|
||||
public void setOutgoing(IBasicBlock exit) {
|
||||
if (this.next != null)
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot modify already exiting connector"); //$NON-NLS-1$
|
||||
this.next = exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.cdt.codan.internal.core.cfg.AbstractBasicBlock#addOutgoing
|
||||
* (org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock)
|
||||
*/
|
||||
@Override
|
||||
public void addOutgoing(IBasicBlock node) {
|
||||
setOutgoing(node);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*******************************************************************************
|
||||
* 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 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;
|
||||
|
||||
/**
|
||||
* TODO: add description
|
||||
*/
|
||||
public class ConnectorNode extends AbstractSingleOutgoingNode implements
|
||||
IConnectorNode {
|
||||
ArrayList<IBasicBlock> incoming = new ArrayList<IBasicBlock>(2);
|
||||
|
||||
/**
|
||||
* @param next
|
||||
*/
|
||||
public ConnectorNode() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
public void addIncoming(IBasicBlock node) {
|
||||
incoming.add(node);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock#
|
||||
* getIncomingIterator()
|
||||
*/
|
||||
public Iterator<IBasicBlock> getIncomingIterator() {
|
||||
return incoming.iterator();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock#getIncomingSize
|
||||
* ()
|
||||
*/
|
||||
public int getIncomingSize() {
|
||||
// TODO Auto-generated method stub
|
||||
return incoming.size();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/*******************************************************************************
|
||||
* 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 java.util.ArrayList;
|
||||
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.IControlFlowGraph;
|
||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionArc;
|
||||
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.ISingleOutgoing;
|
||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode;
|
||||
|
||||
/**
|
||||
* TODO: add description
|
||||
*/
|
||||
public class ControlFlowGraph implements IControlFlowGraph {
|
||||
private List<IExitNode> exitNodes;
|
||||
private IStartNode start;
|
||||
|
||||
public ControlFlowGraph(IStartNode start, Collection<IExitNode> exitNodes) {
|
||||
setExitNodes(exitNodes);
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
public Iterator<IExitNode> getExitNodeIterator() {
|
||||
return exitNodes.iterator();
|
||||
}
|
||||
|
||||
public int getExitNodeSize() {
|
||||
return exitNodes.size();
|
||||
}
|
||||
|
||||
public void setExitNodes(Collection<IExitNode> exitNodes) {
|
||||
if (this.exitNodes != null)
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot modify already exiting connector"); //$NON-NLS-1$
|
||||
this.exitNodes = Collections.unmodifiableList(new ArrayList<IExitNode>(
|
||||
exitNodes));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IControlFlowGraph#
|
||||
* getStartNode()
|
||||
*/
|
||||
public IStartNode getStartNode() {
|
||||
return start;
|
||||
}
|
||||
|
||||
void setStartNode(IStartNode start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
public void print(IBasicBlock node) {
|
||||
System.out.println(node.toString());
|
||||
if (node instanceof IConnectorNode)
|
||||
return;
|
||||
if (node instanceof IDecisionNode) {
|
||||
// todo
|
||||
Iterator<IDecisionArc> decisionArcs = ((IDecisionNode) node)
|
||||
.getDecisionArcs();
|
||||
for (; decisionArcs.hasNext();) {
|
||||
IDecisionArc arc = decisionArcs.next();
|
||||
System.out.println("{" + arc.getIndex() + ":");
|
||||
print(arc.getOutgoing());
|
||||
System.out.println("}");
|
||||
}
|
||||
print(((IDecisionNode) node).getConnectionNode());
|
||||
} else if (node instanceof ISingleOutgoing) {
|
||||
print(((ISingleOutgoing) node).getOutgoing());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IControlFlowGraph#
|
||||
* getUnconnectedNodeIterator()
|
||||
*/
|
||||
public Iterator<IBasicBlock> getUnconnectedNodeIterator() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
/*******************************************************************************
|
||||
* 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 java.util.ArrayList;
|
||||
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;
|
||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode;
|
||||
|
||||
/**
|
||||
* @see {@link IDecisionNode}
|
||||
*/
|
||||
public class DecisionNode extends AbstractSingleIncomingNode implements
|
||||
IDecisionNode {
|
||||
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
|
||||
*/
|
||||
public DecisionNode(IBasicBlock prev) {
|
||||
super(prev);
|
||||
}
|
||||
|
||||
public void setDecisionArcs(Collection<IDecisionArc> next) {
|
||||
this.next = Collections.unmodifiableList(new ArrayList<IDecisionArc>(
|
||||
next));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOutgoing(IBasicBlock node) {
|
||||
DecisionArc arc = new DecisionArc(getDecisionArcSize(), node);
|
||||
next.add(arc);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode#
|
||||
* getDecisionArcs()
|
||||
*/
|
||||
public Iterator<IDecisionArc> getDecisionArcs() {
|
||||
return next.iterator();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode#
|
||||
* getDecisionArcSize()
|
||||
*/
|
||||
public int getDecisionArcSize() {
|
||||
return next.size();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock#
|
||||
* getOutgoingIterator()
|
||||
*/
|
||||
public Iterator<IBasicBlock> getOutgoingIterator() {
|
||||
return new Iterator<IBasicBlock>() {
|
||||
private Iterator<IDecisionArc> it;
|
||||
{
|
||||
it = next.iterator();
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return it.hasNext();
|
||||
}
|
||||
|
||||
public IBasicBlock next() {
|
||||
IDecisionArc arc = it.next();
|
||||
return arc.getOutgoing();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock#getOutgoingSize
|
||||
* ()
|
||||
*/
|
||||
public int getOutgoingSize() {
|
||||
return next.size();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode#
|
||||
* getConnectionNode()
|
||||
*/
|
||||
public IConnectorNode getConnectionNode() {
|
||||
return conn;
|
||||
}
|
||||
|
||||
public void setConnectorNode(IConnectorNode conn) {
|
||||
this.conn = conn;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
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.IExitNode;
|
||||
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;
|
||||
private IStartNode start;
|
||||
|
||||
public ExitNode(IBasicBlock prev, IStartNode start) {
|
||||
super();
|
||||
this.prev = prev;
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
public Iterator<IBasicBlock> getIncomingIterator() {
|
||||
return new OneElementIterator<IBasicBlock>(prev);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Iterator<IBasicBlock> getOutgoingIterator() {
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOutgoing(IBasicBlock node) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
|
@ -1,47 +1,33 @@
|
|||
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.IConnectorNode;
|
||||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IJumpNode;
|
||||
|
||||
/**
|
||||
* Plain node has one prev one jump
|
||||
*
|
||||
* Jump node is node that connects unusual control pass, such as goto, break and
|
||||
* continue
|
||||
*
|
||||
*/
|
||||
public class JumpNode extends AbstarctBasicBlock implements IJumpNode {
|
||||
final private IBasicBlock entry;
|
||||
private IBasicBlock jump;
|
||||
public class JumpNode extends AbstractSingleIncomingNode implements IJumpNode {
|
||||
private IConnectorNode jump;
|
||||
private boolean backward;
|
||||
|
||||
public JumpNode(IBasicBlock entry, IBasicBlock jump, boolean backward) {
|
||||
super();
|
||||
this.entry = entry;
|
||||
public JumpNode(IBasicBlock entry, IConnectorNode jump, boolean backward) {
|
||||
super(entry);
|
||||
this.jump = jump;
|
||||
this.backward = backward;
|
||||
}
|
||||
|
||||
public Iterator<IBasicBlock> getIncomingIterator() {
|
||||
return new OneElementIterator<IBasicBlock>(entry);
|
||||
}
|
||||
|
||||
public Iterator<IBasicBlock> getOutgoingIterator() {
|
||||
return new OneElementIterator<IBasicBlock>(jump);
|
||||
}
|
||||
|
||||
public int getIncomingSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public int getOutgoingSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public IBasicBlock getIncoming() {
|
||||
return entry;
|
||||
}
|
||||
|
||||
public IBasicBlock getOutgoing() {
|
||||
return jump;
|
||||
}
|
||||
|
@ -50,9 +36,10 @@ public class JumpNode extends AbstarctBasicBlock implements IJumpNode {
|
|||
return backward;
|
||||
}
|
||||
|
||||
public void setJump(IBasicBlock jump) {
|
||||
if (!(jump instanceof IConnectorNode))
|
||||
throw new IllegalArgumentException("Jump target must be a connection node"); //$NON-NLS-1$
|
||||
public void setJump(IConnectorNode jump) {
|
||||
if (this.jump != null)
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot modify exiting connector"); //$NON-NLS-1$
|
||||
this.jump = jump;
|
||||
}
|
||||
|
||||
|
@ -60,4 +47,8 @@ public class JumpNode extends AbstarctBasicBlock implements IJumpNode {
|
|||
this.backward = backward;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOutgoing(IBasicBlock node) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,45 +6,45 @@ import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock;
|
|||
import org.eclipse.cdt.codan.provisional.core.model.cfg.IPlainNode;
|
||||
|
||||
/**
|
||||
* Plain node has one prev one jump
|
||||
*
|
||||
* Plain node has one incoming arc and one outgoing arc
|
||||
*
|
||||
*/
|
||||
public class PlainNode extends AbstarctBasicBlock implements IPlainNode {
|
||||
final IBasicBlock prev;
|
||||
public class PlainNode extends AbstractSingleIncomingNode implements IPlainNode {
|
||||
IBasicBlock next;
|
||||
|
||||
public PlainNode(IBasicBlock entry, IBasicBlock exit) {
|
||||
super();
|
||||
this.prev = entry;
|
||||
this.next = exit;
|
||||
}
|
||||
|
||||
public Iterator<IBasicBlock> getIncomingIterator() {
|
||||
return new OneElementIterator<IBasicBlock>(prev);
|
||||
public PlainNode(IBasicBlock prev, IBasicBlock next) {
|
||||
super(prev);
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public Iterator<IBasicBlock> getOutgoingIterator() {
|
||||
return new OneElementIterator<IBasicBlock>(next);
|
||||
}
|
||||
|
||||
public int getIncomingSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public int getOutgoingSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public IBasicBlock getIncoming() {
|
||||
return prev;
|
||||
}
|
||||
|
||||
public IBasicBlock getOutgoing() {
|
||||
return next;
|
||||
}
|
||||
|
||||
public void setOutgoing(IBasicBlock exit) {
|
||||
if (this.next != null) throw new IllegalArgumentException("Cannot modify already exiting connector"); //$NON-NLS-1$
|
||||
if (this.next != null)
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot modify already exiting connector"); //$NON-NLS-1$
|
||||
this.next = exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.cdt.codan.internal.core.cfg.AbstractBasicBlock#addOutgoing
|
||||
* (org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock)
|
||||
*/
|
||||
@Override
|
||||
public void addOutgoing(IBasicBlock node) {
|
||||
setOutgoing(node);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +1,17 @@
|
|||
package org.eclipse.cdt.codan.internal.core.cfg;
|
||||
|
||||
import java.util.ArrayList;
|
||||
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.IStartNode;
|
||||
|
||||
/**
|
||||
* Start node has no prev, one jump and it is connect to function exits
|
||||
*
|
||||
* Start node has no incoming, one outgoing and it is connect to function exits
|
||||
*
|
||||
*/
|
||||
public class StartNode extends AbstarctBasicBlock implements IStartNode {
|
||||
private IBasicBlock next;
|
||||
private List<IBasicBlock> exitNodes;
|
||||
|
||||
public StartNode(IBasicBlock next, Collection<IBasicBlock> exitNodes) {
|
||||
super();
|
||||
this.next = next;
|
||||
if (exitNodes != null) this.exitNodes = Collections.unmodifiableList(new ArrayList<IBasicBlock>(exitNodes));
|
||||
else this.exitNodes = null; // incomplete node
|
||||
public class StartNode extends AbstractSingleOutgoingNode implements IStartNode {
|
||||
public StartNode(IBasicBlock next) {
|
||||
super(next);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -29,37 +19,12 @@ public class StartNode extends AbstarctBasicBlock implements IStartNode {
|
|||
return Collections.EMPTY_LIST.iterator();
|
||||
}
|
||||
|
||||
public Iterator<IBasicBlock> getOutgoingIterator() {
|
||||
return new OneElementIterator<IBasicBlock>(next);
|
||||
}
|
||||
|
||||
public int getIncomingSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getOutgoingSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public IBasicBlock getOutgoing() {
|
||||
return next;
|
||||
}
|
||||
|
||||
public Iterator<IBasicBlock> getExitNodeIterator() {
|
||||
return exitNodes.iterator();
|
||||
}
|
||||
|
||||
public int getExitNodeSize() {
|
||||
return exitNodes.size();
|
||||
}
|
||||
|
||||
public void setOutgoing(IBasicBlock next) {
|
||||
if (this.next != null) throw new IllegalArgumentException("Cannot modify already exiting connector"); //$NON-NLS-1$
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public void setExitNodes(Collection<IBasicBlock> exitNodes) {
|
||||
if (this.exitNodes != null) throw new IllegalArgumentException("Cannot modify already exiting connector"); //$NON-NLS-1$
|
||||
this.exitNodes = Collections.unmodifiableList(new ArrayList<IBasicBlock>(exitNodes));
|
||||
@Override
|
||||
public void addOutgoing(IBasicBlock node) {
|
||||
setOutgoing(node);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,15 @@ package org.eclipse.cdt.codan.provisional.core.model.cfg;
|
|||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
*
|
||||
* Control flow graph basic block node - superinterface of all nodes. Each node
|
||||
* has iterator and size over incoming and outgoing arc
|
||||
* <p/>
|
||||
* The following are speciazed versions of the nodes:
|
||||
* <li>{@link IStartNode} - start node of the graph
|
||||
* <li>{@link I}
|
||||
*/
|
||||
public interface IBasicBlock {
|
||||
Iterator<IBasicBlock> getIncomingIterator();
|
||||
|
||||
|
@ -10,5 +19,4 @@ public interface IBasicBlock {
|
|||
int getIncomingSize();
|
||||
|
||||
int getOutgoingSize();
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
package org.eclipse.cdt.codan.provisional.core.model.cfg;
|
||||
|
||||
public interface IConnectorNode extends IBasicBlock {
|
||||
|
||||
public interface IConnectorNode extends IBasicBlock, ISingleOutgoing {
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* TODO: add description
|
||||
*/
|
||||
public interface IControlFlowGraph {
|
||||
IStartNode getStartNode();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Iterator<IExitNode> getExitNodeIterator();
|
||||
|
||||
int getExitNodeSize();
|
||||
|
||||
Iterator<IBasicBlock> getUnconnectedNodeIterator();
|
||||
}
|
|
@ -1,5 +1,31 @@
|
|||
package org.eclipse.cdt.codan.provisional.core.model.cfg;
|
||||
|
||||
public interface IDecisionArc {
|
||||
/**
|
||||
* Arc that has a condition upon it, for example if branches have true/false
|
||||
* condition, and switch branches have case condition
|
||||
*/
|
||||
public interface IDecisionArc extends ISingleOutgoing {
|
||||
/**
|
||||
* Index represent branch index in decision node, as well semantics: <br>
|
||||
* 0 - always a false (else) branch of if, and default branch for switch,
|
||||
* even if no code exists <br>
|
||||
* 1 - is true (then) branch for if
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int getIndex();
|
||||
|
||||
/**
|
||||
* Basic block that is at the end of the arc
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
IBasicBlock getOutgoing();
|
||||
|
||||
/**
|
||||
* Return parent node (decision node) or the decision arc
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
IDecisionNode getDecisionNode();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,17 @@
|
|||
package org.eclipse.cdt.codan.provisional.core.model.cfg;
|
||||
|
||||
public interface IDecisionNode extends IBasicBlock {
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
*
|
||||
* Interface for decision node. This node represent condition node in the graph,
|
||||
* it has one incoming arc and many outgoing, each of them has a value of
|
||||
* condition associated with it.
|
||||
*/
|
||||
public interface IDecisionNode extends IBasicBlock, ISingleIncoming {
|
||||
Iterator<IDecisionArc> getDecisionArcs();
|
||||
|
||||
int getDecisionArcSize();
|
||||
|
||||
IConnectorNode getConnectionNode();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Exit node of the graph. Usually return from the function, can also be throw
|
||||
* or abort, such at exit(0) call.
|
||||
*
|
||||
*/
|
||||
public interface IExitNode extends IBasicBlock, ISingleIncoming {
|
||||
IStartNode getStartNode();
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
package org.eclipse.cdt.codan.provisional.core.model.cfg;
|
||||
|
||||
public interface IPlainNode extends IBasicBlock, ISingleOutgoing, ISingleIncoming {
|
||||
|
||||
public interface IPlainNode extends IBasicBlock, ISingleOutgoing,
|
||||
ISingleIncoming {
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package org.eclipse.cdt.codan.provisional.core.model.cfg;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Start node of the control flow graph. Each graph has only one start node. It
|
||||
* has no incoming arcs and one outgoing arc. It also contains iterator for
|
||||
* function exit nodes.
|
||||
*/
|
||||
public interface IStartNode extends IBasicBlock, ISingleOutgoing {
|
||||
Iterator<IBasicBlock> getExitNodeIterator();
|
||||
|
||||
int getExitNodeSize();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue