/* Soot - a J*va Optimization Framework
* Copyright (C) 2003 Ondrej Lhotak
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
package soot.jimple.toolkits.pointer;
import soot.*;
import java.util.*;
/** Represents a set of (local,type) pairs using a bit-vector. */
class LocalTypeSet extends java.util.BitSet {
protected List<Local> locals;
protected List<Type> types;
/** Constructs a new empty set given a list of all locals and types that may
* ever be in the set. */
public LocalTypeSet( List<Local> locals, List<Type> types ) {
super( locals.size() * types.size() );
this.locals = locals;
this.types = types;
if( !Scene.v().hasFastHierarchy() ) {
Scene.v().setFastHierarchy( new FastHierarchy() );
}
}
/** Returns the number of the bit corresponding to the pair (l,t). */
protected int indexOf( Local l, RefType t ) {
if( locals.indexOf( l ) == -1 || types.indexOf( t ) == -1 ) {
throw new RuntimeException( "Invalid local or type in LocalTypeSet" );
}
return locals.indexOf( l ) * types.size() + types.indexOf( t );
}
/** Removes all pairs corresponding to local l from the set. */
public void killLocal( Local l ) {
int base = types.size() * locals.indexOf( l );
for( int i = 0; i < types.size(); i++ ) {
clear( i + base );
}
}
/** For each pair (from,t), adds a pair (to,t). */
public void localCopy( Local to, Local from ) {
int baseTo = types.size() * locals.indexOf( to );
int baseFrom = types.size() * locals.indexOf( from );
for( int i = 0; i < types.size(); i++ ) {
if( get( i+baseFrom ) ) {
set( i+baseTo );
} else {
clear( i+baseTo );
}
}
}
/** Empties the set. */
public void clearAllBits() {
for( int i = 0; i < types.size() * locals.size(); i++ ) {
clear( i );
}
}
/** Fills the set to contain all possible (local,type) pairs. */
public void setAllBits() {
for( int i = 0; i < types.size() * locals.size(); i++ ) {
set( i );
}
}
/** Adds to the set all pairs (l,type) where type is any supertype of t. */
public void localMustBeSubtypeOf( Local l, RefType t ) {
FastHierarchy fh = Scene.v().getFastHierarchy();
for (Type type : types) {
RefType supertype = (RefType) type;
if( fh.canStoreType( t, supertype ) ) {
set( indexOf( l, supertype ) );
}
}
}
public String toString(){
StringBuffer sb = new StringBuffer();
Iterator<Local> localsIt = locals.iterator();
while (localsIt.hasNext()){
Local l = localsIt.next();
Iterator<Type> typesIt = types.iterator();
while (typesIt.hasNext()){
RefType t = (RefType)typesIt.next();
int index = indexOf(l, t);
//G.v().out.println("for: "+l+" and type: "+t+" at: "+index);
if (get(index)) {
sb.append("(("+l+","+t+") -> elim cast check) ");
}
}
}
return sb.toString();
}
}