00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef CBZ_DISMANTLE_H
00038 #define CBZ_DISMANTLE_H
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #define INDEX_IS_PRIMITIVE 0x00000001
00053
00054
00055
00056 #define NO_MULTIPLE_INDIRECTION 0x00000002
00057
00058
00059
00060 #define DISMANTLE_LOGICAL_TO_GOTOS 0x00000004
00061
00062
00063
00064 #define TWO_JUMP_IF 0x00000008
00065
00066
00067
00068 #define LOOP_INVERSION 0x00000010
00069
00070
00071
00072 #define INVERT_CONDITIONALS 0x00000020
00073
00074
00075
00076 #define CONVERT_LOGICALS_TO_IFS 0x00000040
00077
00078 #define DEFAULT_DISMANTLER_FLAGS (NO_MULTIPLE_INDIRECTION \
00079 |DISMANTLE_LOGICAL_TO_GOTOS \
00080 |TWO_JUMP_IF \
00081 |CONVERT_LOGICALS_TO_IFS)
00082
00083
00084
00085
00086
00087 class DismantleChanger: public Changer {
00088
00089
00090
00091 unsigned int label_count;
00092
00093
00094
00095
00096 string prepend_to_label;
00097
00098
00099
00100 string new_label (void) {
00101 char s[20];
00102
00103 sprintf (s, "%d", label_count++);
00104 return prepend_to_label + s;
00105 }
00106
00107 public:
00108 unsigned int dismantle_flags;
00109
00110
00111
00112 char *prefix;
00113
00114
00115
00116
00117 blockNode *clone_empty_stmt (void) {
00118 blockNode *b = new blockNode (NULL, NULL);
00119 b->stmts().push_back (new exprstmtNode (NULL));
00120 return b;
00121 }
00122
00123
00124
00125 idNode *new_id (char *s = "") {
00126 string t("__");
00127 t += s;
00128 t += new_label();
00129 idNode *i = new idNode (t.c_str());
00130 return i;
00131 }
00132
00133
00134
00135 DismantleChanger (Order ord, string pre,
00136 unsigned int flags = DEFAULT_DISMANTLER_FLAGS) :
00137 Changer(ord, Subtree, false),
00138 label_count(0),
00139 prepend_to_label(pre),
00140 dismantle_flags(flags) {}
00141 };
00142
00143
00144
00145 class LoopDismantleChanger: public DismantleChanger {
00146 private:
00147 idNode *return_label;
00148 idNode *return_val;
00149 returnNode *return_node;
00150
00151
00152
00153 Node * dismantle_while_for_loop (whileNode *, idNode *);
00154 Node * dismantle_while_for_loop_with_inversion (whileNode *, idNode *);
00155
00156
00157
00158 Node * dismantle_while_loop (whileNode *);
00159
00160
00161
00162 Node * dismantle_for_loop (forNode *);
00163
00164
00165
00166 Node * dismantle_do_loop (doNode *);
00167
00168
00169
00170 Node * at_loop (loopNode *, Order);
00171 Node * at_return (returnNode *, Order);
00172 Node * at_proc (procNode *, Order);
00173
00174 public:
00175
00176
00177
00178 Node * dismantle_loop (loopNode *);
00179
00180
00181
00182 static exprNode * Not (exprNode *);
00183
00184
00185
00186
00187 static stmtNode * fix_break_continue
00188 (stmtNode *, idNode *, idNode *, bool);
00189
00190
00191
00192
00193
00194
00195 LoopDismantleChanger (unsigned int flags) :
00196 DismantleChanger (Preorder, "L", flags) {}
00197 };
00198
00199
00200
00201 class SelectionDismantleChanger: public DismantleChanger {
00202
00203
00204 Node * dismantle_if (ifNode *);
00205 Node * dismantle_ifelse (ifNode *);
00206
00207
00208
00209 Node * dismantle_switch (switchNode *);
00210
00211
00212
00213 Node * at_selection (selectionNode *, Order);
00214 Node * at_case (caseNode *, Order);
00215
00216
00217 public:
00218
00219
00220
00221 Node * dismantle_selection (selectionNode *);
00222
00223 SelectionDismantleChanger (unsigned int flags) :
00224 DismantleChanger (Preorder, "S", flags) {}
00225 };
00226
00227 class IfConverterChanger: public DismantleChanger {
00228
00229 Node * at_if (ifNode *, Order);
00230 Node * at_if_noelse (ifNode *, Order);
00231
00232 public:
00233
00234 bool change;
00235
00236 IfConverterChanger (unsigned int flags) :
00237 change(false),
00238 DismantleChanger (Preorder, "S", flags) {}
00239 };
00240
00241
00242
00243
00244
00245 class InitializerDismantleChanger: public DismantleChanger {
00246 public:
00247 Node * at_block (blockNode *, Order);
00248 Node * at_label (labelNode *, Order);
00249 InitializerDismantleChanger (unsigned int flags) :
00250 DismantleChanger (Preorder, "", flags) {}
00251 };
00252
00253
00254
00255
00256
00257 class ExpressionDismantleChanger: public DismantleChanger {
00258 blockNode *code;
00259 int recursion_level;
00260 void emit_stmt (stmtNode *);
00261 void emit_decl (idNode *, typeNode *);
00262 void emit_expr (exprNode *);
00263 void emit_temp_assign (exprNode *);
00264
00265
00266
00267 idNode *make_int (void);
00268 idNode *make_var (exprNode *);
00269
00270 public:
00271 Node * at_block (blockNode *, Order);
00272 exprNode * dismantle_expr (exprNode *);
00273 exprNode * dismantle_binary (binaryNode *);
00274 exprNode * dismantle_unary (unaryNode *);
00275 exprNode * dismantle_cast (castNode *);
00276 exprNode * dismantle_comma (commaNode *);
00277 exprNode * dismantle_ternary (ternaryNode *);
00278 exprNode * dismantle_call (callNode *);
00279 exprNode * dismantle_opeq (binaryNode *, unsigned int);
00280 ExpressionDismantleChanger (unsigned int flags) :
00281 DismantleChanger (Postorder, "E", flags) {}
00282 };
00283
00284 class FlattenDismantleChanger: public DismantleChanger {
00285 private:
00286 int _change;
00287 map <string,bool> *labels;
00288 bool unreachable;
00289
00290
00291
00292 stmt_list_p search_target (stmt_list_p, gotoNode *, stmt_list_p);
00293
00294
00295
00296 void search_and_replace_labels (stmt_list, stmt_list_p, stmt_list_p);
00297
00298 public:
00299
00300 Node * at_label (labelNode *, Order);
00301 Node * at_proc (procNode *, Order);
00302 Node * at_unary (unaryNode *, Order);
00303 void flatten_block (blockNode *, blockNode *);
00304 int change (void) { return _change; }
00305
00306 FlattenDismantleChanger (map<string,bool> *l, unsigned int flags) :
00307 DismantleChanger (Both, "", flags),
00308 _change(0), labels(l) {}
00309
00310 };
00311
00312 class UsedLabelWalker: public Walker {
00313 private:
00314
00315 map<string,bool> *_labels;
00316
00317 public:
00318
00319 map<string,bool> * labels (void) {
00320 return _labels;
00321 }
00322
00323 void at_goto (gotoNode *p, Order) {
00324 (*_labels)[p->name()] = true;
00325 }
00326
00327 UsedLabelWalker (void): Walker (Preorder, Subtree) {
00328 _labels = new map<string,bool>;
00329 }
00330 };
00331
00332 class Dismantle {
00333 public:
00334 static void dismantle (unitNode *, unsigned int flags = 0);
00335 };
00336
00337
00338
00339
00340
00341
00342
00343
00344 #define FROM_FOR_TEST1 1
00345 #define FROM_FOR_TEST2 2
00346 #define FROM_WHILE_TEST1 3
00347 #define FROM_WHILE_TEST2 4
00348 #define FROM_DO 5
00349 #define FROM_WHILE 6
00350 #define FROM_IF 7
00351 #define FROM_IFELSE 8
00352 #define FROM_SWITCH 9
00353 #define FROM_TERNARY 10
00354 #define FROM_AND1 11
00355 #define FROM_AND2 12
00356 #define FROM_OR1 13
00357 #define FROM_OR2 14
00358 #define FROM_MANY_CASES 15
00359
00360 class fromAnnote : public Annote {
00361 private:
00362 int _from;
00363 public:
00364 fromAnnote (int f) : _from(f) { }
00365
00366 int from (void) { return _from; }
00367 void from (int f) { _from = f; }
00368 bool is_annote_kind (string & name) {
00369 switch (_from) {
00370 case FROM_FOR_TEST1: return name == "from_for_test1";
00371 case FROM_FOR_TEST2: return name == "from_for_test2";
00372 case FROM_WHILE_TEST1: return name == "from_while_test1";
00373 case FROM_WHILE_TEST2: return name == "from_while_test2";
00374 case FROM_DO: return name == "from_do";
00375 case FROM_IF: return name == "from_if";
00376 case FROM_IFELSE: return name == "from_ifelse";
00377 case FROM_SWITCH: return name == "from_switch";
00378 case FROM_TERNARY: return name == "from_ternary";
00379 case FROM_AND1: return name == "from_and1";
00380 case FROM_AND2: return name == "from_and2";
00381 case FROM_OR1: return name == "from_or1";
00382 case FROM_OR2: return name == "from_or2";
00383 case FROM_MANY_CASES: return name == "from_many_cases";
00384 default: return false;
00385 }
00386 }
00387
00388
00389
00390 static bool find_from (Node *n, string s) {
00391 annote_list_p a;
00392 for (a=n->annotations().begin();
00393 a!=n->annotations().end(); a++) {
00394 if ((*a)->is_annote_kind (s)) return true;
00395 }
00396 return false;
00397 }
00398 };
00399
00400 #endif // CBZ_DISMANTLE_H