001 /* Copyright 2000, 2001, Compaq Computer Corporation */
002
003 package escjava.translate;
004
005
006 import java.util.Hashtable;
007 import java.util.Enumeration;
008
009 import javafe.ast.*;
010 import javafe.util.Set;
011 import javafe.util.Assert;
012
013 import escjava.ast.*;
014 import escjava.ast.TagConstants;
015
016
017 /**
018 ** Provides methods for computing various kinds of syntactic targets
019 **/
020
021 public final class Targets {
022
023 /** Returns the set of normal targets of <code>gc</code>.
024 * In ESCJ 16 speak, this method returns <code>NTargets[[ gc, {} ]]</code>.
025 **/
026
027 //@ ensures \result != null;
028 public static Set normal(/*@ non_null */ GuardedCmd gc) {
029 // use the SimpleTargets option (see ESCJ 16)
030 Set answer = new Set();
031 simpleTargets(gc, answer, true);
032 return answer;
033 }
034
035 /** Returns the set of variables that are direct normal targets in
036 * <code>gc</code>, that is, that are modified in some assignment
037 * statement, not call statement, in <code>gc</code>.
038 **/
039
040 //@ ensures \result != null;
041 public static Set direct(/*@ non_null */ GuardedCmd gc) {
042 // use the SimpleTargets option (see ESCJ 16)
043 Set answer = new Set();
044 simpleTargets(gc, answer, false);
045 return answer;
046 }
047
048 /** Adds <code>SimpleTargets[[ gc ]]</code> (as defined in ESCJ 16)
049 * to <code>set</code>. Assumes that no local variable declared in
050 * <code>gc</code> is in <code>set</code>. If
051 * <code>includeCallTargets</code> is <code>true</code>, the targets of
052 * calls are included; otherwise, they are not.
053 **/
054
055 private static void simpleTargets(/*@ non_null */ GuardedCmd gc, Set set,
056 boolean includeCallTargets) {
057 int tag = gc.getTag();
058 switch (tag) {
059 case TagConstants.SKIPCMD:
060 case TagConstants.RAISECMD:
061 case TagConstants.ASSERTCMD:
062 case TagConstants.ASSUMECMD:
063 return;
064
065 case TagConstants.GETSCMD: {
066 GenericVarDecl vd = ((GetsCmd)gc).v.decl;
067 set.add(vd);
068 return;
069 }
070
071 case TagConstants.SUBGETSCMD: {
072 GenericVarDecl vd = ((SubGetsCmd)gc).v.decl;
073 set.add(vd);
074 return;
075 }
076
077 case TagConstants.SUBSUBGETSCMD: {
078 GenericVarDecl vd = ((SubSubGetsCmd)gc).v.decl;
079 set.add(vd);
080 return;
081 }
082
083 case TagConstants.RESTOREFROMCMD: {
084 // no targets
085 return;
086 }
087
088 case TagConstants.VARINCMD: {
089 VarInCmd vc = (VarInCmd)gc;
090 simpleTargets(vc.g, set, includeCallTargets);
091 for (int i = 0; i < vc.v.size(); i++) {
092 GenericVarDecl vd = vc.v.elementAt(i);
093 set.remove(vd);
094 }
095 return;
096 }
097
098 case TagConstants.DYNINSTCMD: {
099 DynInstCmd dc = (DynInstCmd)gc;
100 simpleTargets(dc.g, set, includeCallTargets);
101 return;
102 }
103
104 case TagConstants.SEQCMD: {
105 SeqCmd sc = (SeqCmd)gc;
106 int len = sc.cmds.size();
107 for (int i = 0; i < len; i++) {
108 simpleTargets(sc.cmds.elementAt(i), set, includeCallTargets);
109 }
110 return;
111 }
112
113 case TagConstants.CALL: {
114 Call call = (Call)gc;
115 if (call.inlined) {
116 simpleTargets(call.desugared, set, includeCallTargets);
117 } else if (includeCallTargets) {
118 Enumeration e = call.spec.preVarMap.keys();
119 while (e.hasMoreElements()) {
120 set.add(((GenericVarDecl)e.nextElement()));
121 }
122 }
123 return;
124 }
125
126 case TagConstants.TRYCMD: {
127 CmdCmdCmd tc = (CmdCmdCmd)gc;
128 simpleTargets(tc.g1, set, includeCallTargets);
129 simpleTargets(tc.g2, set, includeCallTargets);
130 return;
131 }
132
133 case TagConstants.LOOPCMD: {
134 LoopCmd lp = (LoopCmd)gc;
135 simpleTargets(lp.guard, set, includeCallTargets);
136 simpleTargets(lp.body, set, includeCallTargets);
137 for (int i = 0; i < lp.tempVars.size(); i++) {
138 GenericVarDecl vd = lp.tempVars.elementAt(i);
139 set.remove(vd);
140 }
141 return;
142 }
143
144 case TagConstants.CHOOSECMD: {
145 CmdCmdCmd cc = (CmdCmdCmd)gc;
146 simpleTargets(cc.g1, set, includeCallTargets);
147 simpleTargets(cc.g2, set, includeCallTargets);
148 return;
149 }
150
151 default:
152 //@ unreachable;
153 Assert.fail("UnknownTag<" + tag + ":" +
154 TagConstants.toString(tag) + ">");
155 return;
156 }
157 }
158
159 }
160