new CAstSymbol type for information about a symbol being declared. new support for default init values for unitialized variables

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@920 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
dolby-oss 2007-04-04 13:02:17 +00:00
parent 10ccb7410e
commit c51ad28e66
6 changed files with 287 additions and 63 deletions

View File

@ -50,6 +50,7 @@ private:
jclass CAstNode; jclass CAstNode;
jclass CAstInterface; jclass CAstInterface;
jclass CAstPrinter; jclass CAstPrinter;
jclass CAstSymbol;
jmethodID castPrint; jmethodID castPrint;
jmethodID makeNode0; jmethodID makeNode0;
jmethodID makeNode1; jmethodID makeNode1;
@ -76,6 +77,10 @@ private:
jmethodID getClass; jmethodID getClass;
jmethodID intValue; jmethodID intValue;
jmethodID _getEntityName; jmethodID _getEntityName;
jmethodID castSymbolInit1;
jmethodID castSymbolInit2;
jmethodID castSymbolInit3;
jmethodID castSymbolInit4;
jobject callReference; jobject callReference;
@ -173,6 +178,14 @@ public:
const char *getEntityName(jobject); const char *getEntityName(jobject);
jobject makeSymbol(const char *);
jobject makeSymbol(const char *, bool);
jobject makeSymbol(const char *, bool, bool);
jobject makeSymbol(const char *, bool, bool, jobject);
void log(jobject); void log(jobject);
}; };
#endif #endif

View File

@ -86,25 +86,51 @@ CAstWrapper::CAstWrapper(JNIEnv *env, Exceptions &ex, jobject Ast)
THROW_ANY_EXCEPTION(java_ex); THROW_ANY_EXCEPTION(java_ex);
this->CAstPrinter = env->FindClass("com/ibm/wala/cast/util/CAstPrinter"); this->CAstPrinter = env->FindClass("com/ibm/wala/cast/util/CAstPrinter");
THROW_ANY_EXCEPTION(java_ex);
this->castPrint = env->GetStaticMethodID(CAstPrinter, "print", "(Lcom/ibm/wala/cast/tree/CAstNode;)Ljava/lang/String;"); this->castPrint = env->GetStaticMethodID(CAstPrinter, "print", "(Lcom/ibm/wala/cast/tree/CAstNode;)Ljava/lang/String;");
THROW_ANY_EXCEPTION(java_ex);
this->hashSetInit = env->GetMethodID(HashSet, "<init>", "()V"); this->hashSetInit = env->GetMethodID(HashSet, "<init>", "()V");
THROW_ANY_EXCEPTION(java_ex);
this->hashSetAdd = env->GetMethodID(HashSet, "add", "(Ljava/lang/Object;)Z"); this->hashSetAdd = env->GetMethodID(HashSet, "add", "(Ljava/lang/Object;)Z");
THROW_ANY_EXCEPTION(java_ex);
this->linkedListInit = env->GetMethodID(LinkedList, "<init>", "()V"); this->linkedListInit = env->GetMethodID(LinkedList, "<init>", "()V");
THROW_ANY_EXCEPTION(java_ex);
this->linkedListAdd = env->GetMethodID(LinkedList, "add", "(Ljava/lang/Object;)Z"); this->linkedListAdd = env->GetMethodID(LinkedList, "add", "(Ljava/lang/Object;)Z");
THROW_ANY_EXCEPTION(java_ex);
jclass obj = env->FindClass( __OBJN ); jclass obj = env->FindClass( __OBJN );
THROW_ANY_EXCEPTION(java_ex);
this->toString = env->GetMethodID(obj, "toString", "()Ljava/lang/String;"); this->toString = env->GetMethodID(obj, "toString", "()Ljava/lang/String;");
THROW_ANY_EXCEPTION(java_ex);
this->getClass = env->GetMethodID(obj, "getClass", "()Ljava/lang/Class;"); this->getClass = env->GetMethodID(obj, "getClass", "()Ljava/lang/Class;");
THROW_ANY_EXCEPTION(java_ex);
jclass intcls = env->FindClass("java/lang/Integer"); jclass intcls = env->FindClass("java/lang/Integer");
THROW_ANY_EXCEPTION(java_ex);
this->intValue = env->GetMethodID(intcls, "intValue", "()I"); this->intValue = env->GetMethodID(intcls, "intValue", "()I");
THROW_ANY_EXCEPTION(java_ex);
jclass castEntity = env->FindClass("com/ibm/wala/cast/tree/CAstEntity"); jclass castEntity = env->FindClass("com/ibm/wala/cast/tree/CAstEntity");
THROW_ANY_EXCEPTION(java_ex);
this->_getEntityName = env->GetMethodID(castEntity, "getName", "()Ljava/lang/String;"); this->_getEntityName = env->GetMethodID(castEntity, "getName", "()Ljava/lang/String;");
CAstSymbol = env->FindClass("com/ibm/wala/cast/tree/impl/CAstSymbolImpl");
THROW_ANY_EXCEPTION(java_ex); THROW_ANY_EXCEPTION(java_ex);
this->castSymbolInit1 =
env->GetMethodID(CAstSymbol, "<init>", "(Ljava/lang/String;)V");
THROW_ANY_EXCEPTION(java_ex);
this->castSymbolInit2 =
env->GetMethodID(CAstSymbol, "<init>", "(Ljava/lang/String;Z)V");
THROW_ANY_EXCEPTION(java_ex);
this->castSymbolInit3 =
env->GetMethodID(CAstSymbol, "<init>", "(Ljava/lang/String;ZZ)V");
THROW_ANY_EXCEPTION(java_ex);
this->castSymbolInit4 =
env->GetMethodID(CAstSymbol, "<init>", "(Ljava/lang/String;ZZLjava/lang/Object;)V");
THROW_ANY_EXCEPTION(java_ex);
} }
#define _CPP_CONSTANTS #define _CPP_CONSTANTS
@ -458,3 +484,59 @@ const char *CAstWrapper::getEntityName(jobject entity) {
return cstr2; return cstr2;
} }
jobject CAstWrapper::makeSymbol(const char *name) {
char *safeName = strndup(name, strlen(name)+1);
jobject val = env->NewStringUTF( safeName );
delete safeName;
jobject s = env->NewObject(CAstSymbol, castSymbolInit1, val);
THROW_ANY_EXCEPTION(java_ex);
LOG(s);
return s;
}
jobject CAstWrapper::makeSymbol(const char *name, bool isFinal) {
char *safeName = strndup(name, strlen(name)+1);
jobject val = env->NewStringUTF( safeName );
delete safeName;
THROW_ANY_EXCEPTION(java_ex);
jobject s = env->NewObject(CAstSymbol, castSymbolInit2, val, isFinal);
LOG(s);
return s;
}
jobject
CAstWrapper::makeSymbol(const char *name, bool isFinal, bool isCaseInsensitive)
{
char *safeName = strndup(name, strlen(name)+1);
jobject val = env->NewStringUTF( safeName );
delete safeName;
jobject s = env->NewObject(CAstSymbol, castSymbolInit3, val, isFinal, isCaseInsensitive);
THROW_ANY_EXCEPTION(java_ex);
LOG(s);
return s;
}
jobject
CAstWrapper::makeSymbol(const char *name,
bool isFinal,
bool isCaseInsensitive,
jobject defaultValue)
{
char *safeName = strndup(name, strlen(name)+1);
jobject val = env->NewStringUTF( safeName );
delete safeName;
jobject s = env->NewObject(CAstSymbol, castSymbolInit4, val, isFinal, isCaseInsensitive, defaultValue);
THROW_ANY_EXCEPTION(java_ex);
LOG(s);
return s;
}

View File

@ -35,15 +35,9 @@ import com.ibm.wala.cast.ir.ssa.EachElementHasNextInstruction;
import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access; import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access;
import com.ibm.wala.cast.loader.AstMethod.DebuggingInformation; import com.ibm.wala.cast.loader.AstMethod.DebuggingInformation;
import com.ibm.wala.cast.loader.AstMethod.LexicalInformation; import com.ibm.wala.cast.loader.AstMethod.LexicalInformation;
import com.ibm.wala.cast.tree.CAstControlFlowMap; import com.ibm.wala.cast.tree.*;
import com.ibm.wala.cast.tree.CAstEntity;
import com.ibm.wala.cast.tree.CAstNode;
import com.ibm.wala.cast.tree.CAstSourcePositionMap;
import com.ibm.wala.cast.tree.CAstType;
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position; import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
import com.ibm.wala.cast.tree.impl.CAstCloner; import com.ibm.wala.cast.tree.impl.*;
import com.ibm.wala.cast.tree.impl.CAstImpl;
import com.ibm.wala.cast.tree.impl.CAstOperator;
import com.ibm.wala.cast.tree.visit.CAstVisitor; import com.ibm.wala.cast.tree.visit.CAstVisitor;
import com.ibm.wala.cast.types.AstTypeReference; import com.ibm.wala.cast.types.AstTypeReference;
import com.ibm.wala.cast.util.CAstPrinter; import com.ibm.wala.cast.util.CAstPrinter;
@ -79,6 +73,8 @@ import com.ibm.wala.util.graph.impl.SparseNumberedGraph;
*/ */
public abstract class AstTranslator extends CAstVisitor { public abstract class AstTranslator extends CAstVisitor {
protected abstract boolean useDefaultInitValues();
protected abstract boolean treatGlobalsAsLexicallyScoped(); protected abstract boolean treatGlobalsAsLexicallyScoped();
protected abstract boolean useLocalValuesForLexicalVars(); protected abstract boolean useLocalValuesForLexicalVars();
@ -928,6 +924,22 @@ public abstract class AstTranslator extends CAstVisitor {
private final static int TYPE_TYPE = 5; private final static int TYPE_TYPE = 5;
protected class FinalCAstSymbol implements CAstSymbol {
private final String _name;
private FinalCAstSymbol(String _name) {
this._name = _name;
}
public String name() { return _name; }
public boolean isFinal() { return true; }
public boolean isCaseInsensitive() { return false; }
public Object defaultInitValue() { return null; }
}
protected interface Symbol { protected interface Symbol {
int valueNumber(); int valueNumber();
@ -940,6 +952,8 @@ public abstract class AstTranslator extends CAstVisitor {
void setConstant(Object s); void setConstant(Object s);
boolean isFinal(); boolean isFinal();
Object defaultInitValue();
} }
public interface Scope { public interface Scope {
@ -953,9 +967,9 @@ public abstract class AstTranslator extends CAstVisitor {
Object getConstantObject(int valueNumber); Object getConstantObject(int valueNumber);
void declare(String name, boolean isFinal, boolean isCaseInsensitive); void declare(CAstSymbol s);
void declare(String name, boolean isFinal, boolean isCaseInsensitive, int valueNumber); void declare(CAstSymbol s, int valueNumber);
boolean isCaseInsensitive(String name); boolean isCaseInsensitive(String name);
@ -981,15 +995,22 @@ public abstract class AstTranslator extends CAstVisitor {
private final Scope definingScope; private final Scope definingScope;
AbstractSymbol(Scope definingScope, boolean isFinalValue) { private Object defaultValue;
AbstractSymbol(Scope definingScope, boolean isFinalValue, Object defaultValue) {
this.definingScope = definingScope; this.definingScope = definingScope;
this.isFinalValue = isFinalValue; this.isFinalValue = isFinalValue;
this.defaultValue = defaultValue;
} }
public boolean isFinal() { public boolean isFinal() {
return isFinalValue; return isFinalValue;
} }
public Object defaultInitValue() {
return defaultValue;
}
public Object constant() { public Object constant() {
return constantValue; return constantValue;
} }
@ -1036,7 +1057,7 @@ public abstract class AstTranslator extends CAstVisitor {
} else if (o instanceof String) { } else if (o instanceof String) {
return getUnderlyingSymtab().getConstant((String) o); return getUnderlyingSymtab().getConstant((String) o);
} else if (o instanceof Boolean) { } else if (o instanceof Boolean) {
return getUnderlyingSymtab().getConstant(o == Boolean.TRUE ? 1 : 0); return getUnderlyingSymtab().getConstant((Boolean) o);
} else if (o instanceof Character) { } else if (o instanceof Character) {
return getUnderlyingSymtab().getConstant(((Character) o).charValue()); return getUnderlyingSymtab().getConstant(((Character) o).charValue());
} else if (o == null) { } else if (o == null) {
@ -1058,20 +1079,22 @@ public abstract class AstTranslator extends CAstVisitor {
return getUnderlyingSymtab().getConstantValue(valueNumber); return getUnderlyingSymtab().getConstantValue(valueNumber);
} }
public void declare(String nm, boolean isFinal, boolean isCaseInsensitive, int vn) { public void declare(CAstSymbol s, int vn) {
String nm = s.name();
Assertions._assert(!contains(nm), nm); Assertions._assert(!contains(nm), nm);
if (isCaseInsensitive) if (s.isCaseInsensitive())
caseInsensitiveNames.put(nm.toLowerCase(), nm); caseInsensitiveNames.put(nm.toLowerCase(), nm);
values.put(nm, makeSymbol(nm, isFinal, vn)); values.put(nm, makeSymbol(s, vn));
} }
public void declare(String nm, boolean isFinal, boolean isCaseInsensitive) { public void declare(CAstSymbol s) {
String nm = s.name();
if (!contains(nm) || lookup(nm).getDefiningScope() != this) { if (!contains(nm) || lookup(nm).getDefiningScope() != this) {
if (isCaseInsensitive) if (s.isCaseInsensitive())
caseInsensitiveNames.put(nm.toLowerCase(), nm); caseInsensitiveNames.put(nm.toLowerCase(), nm);
values.put(nm, makeSymbol(nm, isFinal)); values.put(nm, makeSymbol(s));
} else { } else {
Assertions._assert(!isFinal, "trying to redeclare " + nm); Assertions._assert(!s.isFinal(), "trying to redeclare " + nm);
} }
} }
@ -1084,15 +1107,15 @@ public abstract class AstTranslator extends CAstVisitor {
return (mappedName == null) ? nm : mappedName; return (mappedName == null) ? nm : mappedName;
} }
protected Symbol makeSymbol(String nm, boolean isFinal) { protected Symbol makeSymbol(CAstSymbol s) {
return makeSymbol(nm, isFinal, -1, this); return makeSymbol(s.name(), s.isFinal(), s.defaultInitValue(), -1, this);
} }
protected Symbol makeSymbol(String nm, boolean isFinal, int vn) { protected Symbol makeSymbol(CAstSymbol s, int vn) {
return makeSymbol(nm, isFinal, vn, this); return makeSymbol(s.name(), s.isFinal(), s.defaultInitValue(), vn, this);
} }
abstract protected Symbol makeSymbol(String nm, boolean isFinal, int vn, Scope parent); abstract protected Symbol makeSymbol(String nm, boolean isFinal, Object defaultInitValue, int vn, Scope parent);
public boolean isCaseInsensitive(String nm) { public boolean isCaseInsensitive(String nm) {
return caseInsensitiveNames.containsKey(nm.toLowerCase()); return caseInsensitiveNames.containsKey(nm.toLowerCase());
@ -1104,7 +1127,7 @@ public abstract class AstTranslator extends CAstVisitor {
} else { } else {
Symbol scoped = parent.lookup(nm); Symbol scoped = parent.lookup(nm);
if (scoped != null && getEntityScope() == this && (isGlobal(scoped) || isLexicallyScoped(scoped))) { if (scoped != null && getEntityScope() == this && (isGlobal(scoped) || isLexicallyScoped(scoped))) {
values.put(nm, makeSymbol(nm, scoped.isFinal(), -1, scoped.getDefiningScope())); values.put(nm, makeSymbol(nm, scoped.isFinal(), scoped.defaultInitValue(), -1, scoped.getDefiningScope()));
if (scoped.getDefiningScope().isCaseInsensitive(nm)) { if (scoped.getDefiningScope().isCaseInsensitive(nm)) {
caseInsensitiveNames.put(nm.toLowerCase(), nm); caseInsensitiveNames.put(nm.toLowerCase(), nm);
} }
@ -1158,9 +1181,12 @@ public abstract class AstTranslator extends CAstVisitor {
return TYPE_SCRIPT; return TYPE_SCRIPT;
} }
protected Symbol makeSymbol(final String nm, final boolean isFinal, int vn, Scope definer) { protected Symbol makeSymbol(final String nm, final boolean isFinal, final Object defaultInitValue, int vn, Scope definer) {
final int v = vn == -1 ? getUnderlyingSymtab().newSymbol() : vn; final int v = vn == -1 ? getUnderlyingSymtab().newSymbol() : vn;
return new AbstractSymbol(definer, isFinal) { if (useDefaultInitValues() && defaultInitValue != null) {
getUnderlyingSymtab().setDefaultValue(v, defaultInitValue);
}
return new AbstractSymbol(definer, isFinal, defaultInitValue) {
public String toString() { public String toString() {
return nm + ":" + System.identityHashCode(this); return nm + ":" + System.identityHashCode(this);
} }
@ -1185,8 +1211,19 @@ public abstract class AstTranslator extends CAstVisitor {
// ctor for scope object // ctor for scope object
{ {
for (int i = 0; i < f.getArgumentCount(); i++) for (int i = 0; i < f.getArgumentCount(); i++) {
declare(f.getArgumentNames()[i], false, false); final int yuck = i;
declare(new CAstSymbol() {
public String name() { return f.getArgumentNames()[yuck]; }
public boolean isFinal() { return false; }
public boolean isCaseInsensitive() { return false; }
public Object defaultInitValue() { return null; }
});
}
} }
public SymbolTable getUnderlyingSymtab() { public SymbolTable getUnderlyingSymtab() {
@ -1222,8 +1259,8 @@ public abstract class AstTranslator extends CAstVisitor {
return -1; return -1;
} }
protected Symbol makeSymbol(final String nm, final boolean isFinal, final int valueNumber, Scope definer) { protected Symbol makeSymbol(final String nm, final boolean isFinal, final Object defaultInitValue, final int valueNumber, Scope definer) {
return new AbstractSymbol(definer, isFinal) { return new AbstractSymbol(definer, isFinal, defaultInitValue) {
final int vn; final int vn;
{ {
@ -1236,6 +1273,9 @@ public abstract class AstTranslator extends CAstVisitor {
} else { } else {
vn = getUnderlyingSymtab().newSymbol(); vn = getUnderlyingSymtab().newSymbol();
} }
if (useDefaultInitValues() && defaultInitValue != null) {
getUnderlyingSymtab().setDefaultValue(vn, defaultInitValue);
}
} }
public String toString() { public String toString() {
@ -1276,9 +1316,12 @@ public abstract class AstTranslator extends CAstVisitor {
return ((AbstractScope) getEntityScope()).getEntity(); return ((AbstractScope) getEntityScope()).getEntity();
} }
protected Symbol makeSymbol(final String nm, boolean isFinal, int vn, Scope definer) { protected Symbol makeSymbol(final String nm, boolean isFinal, final Object defaultInitValue, int vn, Scope definer) {
final int v = vn == -1 ? getUnderlyingSymtab().newSymbol() : vn; final int v = vn == -1 ? getUnderlyingSymtab().newSymbol() : vn;
return new AbstractSymbol(definer, isFinal) { if (useDefaultInitValues() && defaultInitValue != null) {
getUnderlyingSymtab().setDefaultValue(v, defaultInitValue);
}
return new AbstractSymbol(definer, isFinal, defaultInitValue) {
public String toString() { public String toString() {
return nm + ":" + System.identityHashCode(this); return nm + ":" + System.identityHashCode(this);
} }
@ -1352,29 +1395,39 @@ public abstract class AstTranslator extends CAstVisitor {
return caseInsensitiveNames.containsKey(name.toLowerCase()); return caseInsensitiveNames.containsKey(name.toLowerCase());
} }
public Symbol lookup(String name) { public Symbol lookup(final String name) {
if (!globalSymbols.containsKey(mapName(name))) if (!globalSymbols.containsKey(mapName(name))) {
if (hasImplicitGlobals()) if (hasImplicitGlobals()) {
declare(name, false, false); declare(new CAstSymbol() {
else if (hasSpecialUndeclaredVariables()) { public String name() { return name; }
public boolean isFinal() { return false; }
public boolean isCaseInsensitive() { return false; }
public Object defaultInitValue() { return null; }
});
} else if (hasSpecialUndeclaredVariables()) {
return null; return null;
} else { } else {
throw new Error("cannot find " + name); throw new Error("cannot find " + name);
} }
}
return globalSymbols.get(mapName(name)); return globalSymbols.get(mapName(name));
} }
public void declare(final String name, boolean isFinal, boolean isCaseInsensitive, int vn) { public void declare(CAstSymbol s, int vn) {
Assertions._assert(vn == -1); Assertions._assert(vn == -1);
declare(name, isFinal, isCaseInsensitive); declare(s);
} }
public void declare(final String name, boolean isFinal, boolean isCaseInsensitive) { public void declare(CAstSymbol s) {
if (isCaseInsensitive) { final String name = s.name();
if (s.isCaseInsensitive()) {
caseInsensitiveNames.put(name.toLowerCase(), name); caseInsensitiveNames.put(name.toLowerCase(), name);
} }
globalSymbols.put(name, new AbstractSymbol(this, isFinal) { globalSymbols.put(name, new AbstractSymbol(this, s.isFinal(), s.defaultInitValue()) {
public String toString() { public String toString() {
return name + ":" + System.identityHashCode(this); return name + ":" + System.identityHashCode(this);
} }
@ -1456,16 +1509,17 @@ public abstract class AstTranslator extends CAstVisitor {
} }
} }
public void declare(final String name, boolean isFinal, boolean isCaseInsensitive, int vn) { public void declare(CAstSymbol s, int vn) {
Assertions._assert(vn == -1); Assertions._assert(vn == -1);
declare(name, isFinal, isCaseInsensitive); declare(s);
} }
public void declare(final String name, boolean isFinal, boolean isCaseInsensitive) { public void declare(CAstSymbol s) {
Assertions._assert(!isFinal); final String name = s.name();
if (isCaseInsensitive) Assertions._assert(!s.isFinal());
if (s.isCaseInsensitive())
caseInsensitiveNames.put(name.toLowerCase(), name); caseInsensitiveNames.put(name.toLowerCase(), name);
typeSymbols.put(name, new AbstractSymbol(this, isFinal) { typeSymbols.put(name, new AbstractSymbol(this, s.isFinal(), s.defaultInitValue()) {
public String toString() { public String toString() {
return name + ":" + System.identityHashCode(this); return name + ":" + System.identityHashCode(this);
} }
@ -2206,7 +2260,7 @@ public abstract class AstTranslator extends CAstVisitor {
CAstEntity fn = (CAstEntity) n.getChild(0).getValue(); CAstEntity fn = (CAstEntity) n.getChild(0).getValue();
// FIXME: handle redefinitions of functions // FIXME: handle redefinitions of functions
if (!context.currentScope().contains(fn.getName())) { if (!context.currentScope().contains(fn.getName())) {
context.currentScope().declare(fn.getName(), true, false, result); context.currentScope().declare(new FinalCAstSymbol(fn.getName()), result);
} }
} }
@ -2281,7 +2335,7 @@ public abstract class AstTranslator extends CAstVisitor {
protected void leaveGetCaughtException(CAstNode n, Context c, CAstVisitor visitor) { protected void leaveGetCaughtException(CAstNode n, Context c, CAstVisitor visitor) {
WalkContext context = (WalkContext) c; WalkContext context = (WalkContext) c;
String nm = (String) n.getChild(0).getValue(); String nm = (String) n.getChild(0).getValue();
context.currentScope().declare(nm, true, false); context.currentScope().declare(new FinalCAstSymbol(nm));
context.cfg().addInstruction( context.cfg().addInstruction(
SSAInstructionFactory.GetCaughtExceptionInstruction(context.cfg().getCurrentBlock().getNumber(), context.currentScope() SSAInstructionFactory.GetCaughtExceptionInstruction(context.cfg().getCurrentBlock().getNumber(), context.currentScope()
.lookup(nm).valueNumber())); .lookup(nm).valueNumber()));
@ -2415,23 +2469,22 @@ public abstract class AstTranslator extends CAstVisitor {
// TODO: should we handle exploded declaration nodes here instead? // TODO: should we handle exploded declaration nodes here instead?
protected void leaveDeclStmt(CAstNode n, Context c, CAstVisitor visitor) { protected void leaveDeclStmt(CAstNode n, Context c, CAstVisitor visitor) {
WalkContext context = (WalkContext) c; WalkContext context = (WalkContext) c;
String nm = (String) n.getChild(0).getChild(0).getValue(); CAstSymbol s = (CAstSymbol) n.getChild(0).getValue();
Boolean isFinal = (Boolean) n.getChild(1).getValue(); String nm = s.name();
Boolean isCaseInsensitive = (Boolean) n.getChild(2).getValue();
Scope scope = context.currentScope(); Scope scope = context.currentScope();
if (n.getChildCount() == 4) { if (n.getChildCount() == 2) {
CAstNode v = n.getChild(3); CAstNode v = n.getChild(1);
if (scope.contains(nm) && scope.lookup(nm).getDefiningScope() == scope) { if (scope.contains(nm) && scope.lookup(nm).getDefiningScope() == scope) {
Assertions._assert(isFinal.equals(Boolean.FALSE)); Assertions._assert(! s.isFinal());
context.cfg().addInstruction(new AssignInstruction(scope.lookup(nm).valueNumber(), getValue(v))); context.cfg().addInstruction(new AssignInstruction(scope.lookup(nm).valueNumber(), getValue(v)));
} else if (v.getKind() != CAstNode.CONSTANT && v.getKind() != CAstNode.VAR && v.getKind() != CAstNode.THIS) { } else if (v.getKind() != CAstNode.CONSTANT && v.getKind() != CAstNode.VAR && v.getKind() != CAstNode.THIS) {
scope.declare(nm, isFinal.booleanValue(), isCaseInsensitive.booleanValue(), getValue(v)); scope.declare(s, getValue(v));
} else { } else {
scope.declare(nm, isFinal.booleanValue(), isCaseInsensitive.booleanValue()); scope.declare(s);
context.cfg().addInstruction(new AssignInstruction(context.currentScope().lookup(nm).valueNumber(), getValue(v))); context.cfg().addInstruction(new AssignInstruction(context.currentScope().lookup(nm).valueNumber(), getValue(v)));
} }
} else { } else {
context.currentScope().declare(nm, isFinal.booleanValue(), isCaseInsensitive.booleanValue()); context.currentScope().declare(s);
} }
} }
@ -2979,7 +3032,7 @@ public abstract class AstTranslator extends CAstVisitor {
String id = (String) n.getChild(0).getValue(); String id = (String) n.getChild(0).getValue();
context.cfg().setCurrentBlockAsHandler(); context.cfg().setCurrentBlockAsHandler();
if (!context.currentScope().contains(id)) { if (!context.currentScope().contains(id)) {
context.currentScope().declare(id, true, false); context.currentScope().declare(new FinalCAstSymbol(id));
} }
context.cfg().addInstruction( context.cfg().addInstruction(
SSAInstructionFactory.GetCaughtExceptionInstruction(context.cfg().getCurrentBlock().getNumber(), context.currentScope() SSAInstructionFactory.GetCaughtExceptionInstruction(context.cfg().getCurrentBlock().getNumber(), context.currentScope()

View File

@ -0,0 +1,14 @@
package com.ibm.wala.cast.tree;
public interface CAstSymbol {
public String name();
public boolean isFinal();
public boolean isCaseInsensitive();
public Object defaultInitValue();
}

View File

@ -0,0 +1,62 @@
package com.ibm.wala.cast.tree.impl;
import com.ibm.wala.cast.tree.*;
public class CAstSymbolImpl implements CAstSymbol {
private final String _name;
private final boolean _isFinal;
private final boolean _isCaseInsensitive;
private final Object _defaultInitValue;
public CAstSymbolImpl(String _name) {
this._name = _name;
this._isFinal = false;
this._isCaseInsensitive = false;
this._defaultInitValue = null;
}
public CAstSymbolImpl(String _name, boolean _isFinal) {
this._name = _name;
this._isFinal = _isFinal;
this._isCaseInsensitive = false;
this._defaultInitValue = null;
}
public CAstSymbolImpl(String _name, boolean _isFinal, boolean _isCaseInsensitive) {
this._name = _name;
this._isFinal = _isFinal;
this._isCaseInsensitive = _isCaseInsensitive;
this._defaultInitValue = null;
}
public CAstSymbolImpl(String _name, Object _defaultInitValue) {
this._name = _name;
this._isFinal = false;
this._isCaseInsensitive = false;
this._defaultInitValue = _defaultInitValue;
}
public CAstSymbolImpl(String _name, boolean _isFinal, Object _defaultInitValue) {
this._name = _name;
this._isFinal = _isFinal;
this._isCaseInsensitive = false;
this._defaultInitValue = _defaultInitValue;
}
public CAstSymbolImpl(String _name, boolean _isFinal, boolean _isCaseInsensitive, Object _defaultInitValue) {
this._name = _name;
this._isFinal = _isFinal;
this._isCaseInsensitive = _isCaseInsensitive;
this._defaultInitValue = _defaultInitValue;
}
public String name() { return _name; }
public boolean isFinal() { return _isFinal; }
public boolean isCaseInsensitive() { return _isCaseInsensitive; }
public Object defaultInitValue() { return _defaultInitValue; }
}

View File

@ -474,8 +474,8 @@ public abstract class CAstVisitor {
case CAstNode.DECL_STMT: { case CAstNode.DECL_STMT: {
if (visitor.visitDeclStmt(n, context, visitor)) if (visitor.visitDeclStmt(n, context, visitor))
break; break;
if (n.getChildCount() == 4) if (n.getChildCount() == 2)
visitor.visit(n.getChild(3), context, visitor); visitor.visit(n.getChild(1), context, visitor);
visitor.leaveDeclStmt(n, context, visitor); visitor.leaveDeclStmt(n, context, visitor);
break; break;
} }