package soot.spl.ifds;
import heros.InterproceduralCFG;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import soot.SootMethod;
import soot.Trap;
import soot.Unit;
import soot.jimple.ThrowStmt;
import soot.tagkit.TryCatchTag;
public class ExtendedInterproceduralCFG implements InterproceduralCFG<Unit,SootMethod> {
protected InterproceduralCFG<Unit,SootMethod> delegate;
public ExtendedInterproceduralCFG(InterproceduralCFG<Unit, SootMethod> delegate) {
this.delegate = delegate;
}
public List<Unit> getSuccsOf(Unit n) {
List<Unit> succsOf = delegate.getSuccsOf(n);
if(n instanceof ThrowStmt) {
TryCatchTag tryCatchTag = (TryCatchTag) getMethodOf(n).getActiveBody().getTag(TryCatchTag.NAME);
if(tryCatchTag!=null) {
for(Unit possibleHandlerUnit: succsOf) {
Unit fallThroughUnit = tryCatchTag.getFallThroughUnitOf(possibleHandlerUnit);
if(fallThroughUnit!=null) {
List<Unit> res = new LinkedList<Unit>(succsOf);
res.add(fallThroughUnit);
return res;
}
}
}
}
return succsOf;
}
public boolean isFallThroughSuccessor(Unit stmt, Unit succ) {
if(delegate.isFallThroughSuccessor(stmt, succ))
return true;
if(stmt instanceof ThrowStmt) {
TryCatchTag tryCatchTag = (TryCatchTag) getMethodOf(stmt).getActiveBody().getTag(TryCatchTag.NAME);
if(tryCatchTag!=null) {
for(Unit possibleHandlerUnit: delegate.getSuccsOf(stmt)) {
Unit fallThroughUnit = tryCatchTag.getFallThroughUnitOf(possibleHandlerUnit);
if(fallThroughUnit==succ) {
return true;
}
}
}
}
return false;
}
public boolean isBranchTarget(Unit stmt, Unit succ) {
if(delegate.isBranchTarget(stmt, succ))
return true;
if(stmt instanceof ThrowStmt) {
for(Trap trap: delegate.getMethodOf(stmt).getActiveBody().getTraps()) {
if(trap.getHandlerUnit()==succ) {
return true;
}
}
}
return false;
}
public SootMethod getMethodOf(Unit n) {
return delegate.getMethodOf(n);
}
public Set<SootMethod> getCalleesOfCallAt(Unit n) {
return delegate.getCalleesOfCallAt(n);
}
public Set<Unit> getCallersOf(SootMethod m) {
return delegate.getCallersOf(m);
}
public Set<Unit> getCallsFromWithin(SootMethod m) {
return delegate.getCallsFromWithin(m);
}
public Set<Unit> getStartPointsOf(SootMethod m) {
return delegate.getStartPointsOf(m);
}
public List<Unit> getReturnSitesOfCallAt(Unit n) {
return delegate.getReturnSitesOfCallAt(n);
}
public boolean isCallStmt(Unit stmt) {
return delegate.isCallStmt(stmt);
}
public boolean isExitStmt(Unit stmt) {
return delegate.isExitStmt(stmt);
}
public boolean isStartPoint(Unit stmt) {
return delegate.isStartPoint(stmt);
}
public Set<Unit> allNonCallStartNodes() {
return delegate.allNonCallStartNodes();
}
}