/*******************************************************************************
* Copyright (c) 2009 Red Hat, Inc.
* 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:
* Elliott Baron <ebaron@redhat.com> - initial API and implementation
*******************************************************************************/
package org.eclipse.linuxtools.internal.valgrind.cachegrind.model;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.IFunction;
import org.eclipse.cdt.core.model.IMethod;
import org.eclipse.cdt.core.model.IParent;
import org.eclipse.cdt.core.model.IStructure;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
public class CachegrindFunction implements ICachegrindElement {
private CachegrindFile parent;
private String name;
private List<CachegrindLine> lines;
private long[] totals;
private IAdaptable model;
private static final String SCOPE_RESOLUTION = "::"; //$NON-NLS-1$
public CachegrindFunction(CachegrindFile parent, String name) {
this.parent = parent;
this.name = name;
lines = new ArrayList<>();
IAdaptable pModel = parent.getModel();
if (pModel instanceof ICElement) {
ICElement element = (ICElement) pModel;
try {
if (element instanceof ITranslationUnit) {
// Cachegrind labels parameter types for C++ methods
int paramIndex = name.indexOf('(');
if (paramIndex >= 0) {
name = name.substring(0, paramIndex);
}
model = findElement(name, (IParent) element);
if (model == null) {
while (name.contains(SCOPE_RESOLUTION)) {
String[] parts = name.split(SCOPE_RESOLUTION, 2);
String structureName = parts[0];
name = parts[1];
List<ICElement> dom = ((IParent) element).getChildrenOfType(ICElement.C_CLASS);
dom.addAll(((IParent) element).getChildrenOfType(ICElement.C_STRUCT));
dom.addAll(((IParent) element).getChildrenOfType(ICElement.C_UNION));
for (int i = 0; i < dom.size(); i++) {
ICElement e = dom.get(i);
if (e instanceof IStructure && e.getElementName().equals(structureName)) {
element = e;
}
}
}
model = findElement(name, (IParent) element);
}
}
} catch (CoreException e) {
e.printStackTrace();
}
}
}
private ICElement findElement(String name, IParent parent)
throws CModelException {
ICElement element = null;
List<ICElement> dom = parent.getChildrenOfType(ICElement.C_FUNCTION);
dom.addAll(parent.getChildrenOfType(ICElement.C_METHOD));
for (int i = 0; i < dom.size(); i++) {
ICElement func = dom.get(i);
if ((func instanceof IFunction || func instanceof IMethod) && func.getElementName().equals(name)) {
element = func;
}
}
return element;
}
public void addLine(CachegrindLine line) {
long[] values = line.getValues();
if (totals == null) {
totals = new long[values.length];
}
for (int i = 0; i < values.length; i++) {
totals[i] += values[i];
}
lines.add(line);
}
public String getName() {
return name;
}
@Override
public IAdaptable getModel() {
return model;
}
public long[] getTotals() {
return totals;
}
public CachegrindLine[] getLines() {
return lines.toArray(new CachegrindLine[lines.size()]);
}
@Override
public ICachegrindElement[] getChildren() {
ICachegrindElement[] children = null;
// if there is only a summary don't return any children
if (lines.get(0).getLine() > 0) {
children = getLines();
}
return children;
}
@Override
public ICachegrindElement getParent() {
return parent;
}
@Override
public int compareTo(ICachegrindElement o) {
int result = 0;
if (o instanceof CachegrindFunction) {
result = name.compareTo(((CachegrindFunction) o).getName());
}
return result;
}
}