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