diff options
Diffstat (limited to 'org.eclipse.ptp.pldt.mpi.analysis.cdt/src/org/eclipse/ptp/pldt/mpi/analysis/cdt/graphs/GraphCreator.java')
-rw-r--r-- | org.eclipse.ptp.pldt.mpi.analysis.cdt/src/org/eclipse/ptp/pldt/mpi/analysis/cdt/graphs/GraphCreator.java | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/org.eclipse.ptp.pldt.mpi.analysis.cdt/src/org/eclipse/ptp/pldt/mpi/analysis/cdt/graphs/GraphCreator.java b/org.eclipse.ptp.pldt.mpi.analysis.cdt/src/org/eclipse/ptp/pldt/mpi/analysis/cdt/graphs/GraphCreator.java new file mode 100644 index 0000000..1da923e --- /dev/null +++ b/org.eclipse.ptp.pldt.mpi.analysis.cdt/src/org/eclipse/ptp/pldt/mpi/analysis/cdt/graphs/GraphCreator.java @@ -0,0 +1,192 @@ +/********************************************************************** + * Copyright (c) 2008 IBM Corporation. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.impl.CallGraph; +import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.impl.ResourceCollector; + +/** + * Convenience class for constructing various graphs from C source files + * + * @author Beth Tibbitts + * + */ +public class GraphCreator { + /** + * Convenience method for initializing and computing the call graph in one place. + * <br>This is done in two steps: + * <br>(1) initCallGraph(): initialize call graph with function information + * <br>(2) computeCallGraph(): compute caller/callee/recursive etc. info on the graph + * @param resource + * @return + */ + public ICallGraph createCallGraph(IResource resource) { + ICallGraph cg = initCallGraph(resource); + computeCallGraph(cg); + return cg; + + } + /** + * Create call graph structure from resources (C source files) but caller/callee + * calculations are not done yet; will descend to children of a container if + * called with a folder or project argument. + * @param resource + * @return call graph initialized with basic function information + */ + public ICallGraph initCallGraph(IResource resource) { + ICallGraph callGraph = new CallGraph(); + callGraph = initCallGraph(resource, callGraph); + return callGraph; + + } + /** + * Add information to an existing call graph. + * <br>Will descend to children if this is a container (folder or project) + * + * @param resource contains source file(s) whose functions will be found and added to the call graph. + * @param callGraph + * @return + */ + public ICallGraph initCallGraph(IResource resource, ICallGraph callGraph) { + boolean foundError = resourceCollector(resource, callGraph); + if(foundError) { + System.out.println("Error occurred during call graph creation."); + } + return callGraph; + } + /** + * Create an empty call graph, ready to fill with function information + * later with subsequent calls to initCallGraph(resource, callGraph) + * @return + */ + public ICallGraph initCallGraph() { + return new CallGraph(); + } + /** + * Calculate the caller/callee and recursive properties of the call graph + * @return + */ + public ICallGraph computeCallGraph(ICallGraph callGraph) { + callGraph.buildCG(); + return callGraph; + } + + + /** + * Run analysis ("Resource collector") on a resource (e.g. File or Folder) + * and add the function information found in/under the given resource (file or container) + * to the given call graph + * <br>Will descend to members of folder + * + * @param resource + * the resource selected by the user + * @param callGraph the call graph to which the information will be appended + * @return + */ + public boolean resourceCollector(IResource resource, ICallGraph callGraph) { + + boolean foundError = false; + + // if it's a C file, collect info in the call graph for this file + if (resource instanceof IFile) { + IFile file = (IFile) resource; + String filename = file.getName(); + if (filename.endsWith(".c")) { + ResourceCollector rc = new ResourceCollector(callGraph, file); + rc.run(); + } + // if it's a container, run resourceCollector on each of its members + } else if (resource instanceof IContainer) { + IContainer container = (IContainer) resource; + try { + IResource[] mems = container.members(); + for (int i = 0; i < mems.length; i++) { + boolean err = resourceCollector(mems[i], callGraph); + foundError = foundError || err; + } + } catch (CoreException e) { + e.printStackTrace(); + foundError=true; + } + } else { + // ????? + String name = ""; + if (resource instanceof IResource) { + IResource res = (IResource) resource; + // name=res.getName(); // simple filename only, no path info + IPath path = res.getProjectRelativePath(); + name = path.toString(); + } + System.out.println("Cancelled by User, aborting analysis on subsequent files... " + + name); + } + + return foundError; + } + /** + * Print a call graph structure + * @param cg the call graph to print + */ + public void showCallGraph(ICallGraph cg) { + System.out.println("Show call graph"); + List<ICallGraphNode> nodes = cg.getAllNodes(); + for (Iterator<ICallGraphNode> iterator = nodes.iterator(); iterator.hasNext();) { + ICallGraphNode cgNode = iterator.next(); + printCGNode(cgNode, ""); + //System.out.println(" callers: ==>"); + + for (Iterator<ICallGraphNode> iterator2 = cgNode.getCallers().iterator(); iterator2.hasNext();) { + ICallGraphNode caller = iterator2.next(); + printCGNode(caller," caller: "); + } + //System.out.println(" <== callees:"); + for (Iterator<ICallGraphNode> iterator3 = cgNode.getCallees().iterator(); iterator3.hasNext();) { + ICallGraphNode callee = iterator3.next(); + printCGNode(callee," callee: "); + + } + System.out.println(" "); + + } + List<List<ICallGraphNode>>cycles = cg.getCycles(); + System.out.println("Recursive cycles:"); + for (List<ICallGraphNode> cycle : cycles) { + System.out.println("Cycle: "); + for (Iterator<ICallGraphNode> iterator = cycle.iterator(); iterator.hasNext();) { + ICallGraphNode fn = iterator.next(); + System.out.print(" "+fn.getFuncName()); + + } + System.out.println(" \n"); + } + List<String> vars= cg.getEnv(); + System.out.println("Global variables:"); + for (Iterator<String> varit= vars.iterator(); varit.hasNext();) { + String var = varit.next(); + System.out.println("Global var: "+var); + + } + + } + public void printCGNode(ICallGraphNode cgNode, String prefix) { + System.out.println(prefix+" "+cgNode.getFuncName()+" in "+cgNode.getFileName()); + cgNode.getCFG(); + } +} |