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 #include "c_breeze.h"
00038 #include "print_walker.h"
00039 #include "ref_clone_changer.h"
00040 #include "scope_walker.h"
00041 #include "id_lookup_walker.h"
00042 #include "goto_label_walker.h"
00043 #include "cfg.h"
00044 #include "bits.h"
00045 #include "live.h"
00046 #include "dead.h"
00047 #include "localcopyprop.h"
00048 #include "gc_walker.h"
00049 #include "lir_gen_walker.h"
00050 #include "lir_flow_walker.h"
00051 #include "briggs_reg_alloc.h"
00052 #include "dummy_reg_alloc.h"
00053 #include "asm_gen_walker.h"
00054 #include "dismantle.h"
00055 #include "tree_checker.h"
00056 #include "inliner.h"
00057
00058 #include <unistd.h>
00059
00063
00064
00065
00066
00070 class print_ast_phase : public Phase
00071 {
00072 public:
00073
00074 void run()
00075 {
00076 for (unit_list_p p = CBZ::Program.begin();
00077 p != CBZ::Program.end();
00078 ++p)
00079 print_walker::print(*p, cout);
00080 }
00081 };
00082
00083 Phases Print_AST("ast", new print_ast_phase());
00084
00088 class output_c_phase : public Phase
00089 {
00090 public:
00091
00092 void run()
00093 {
00094 for (unit_list_p p = CBZ::Program.begin();
00095 p != CBZ::Program.end();
00096 ++p) {
00097
00098 unitNode * the_unit = (*p);
00099
00100
00101
00102
00103 if (the_unit->output_file() == "(stdout)") {
00104 output_context a = output_context(cout);
00105 the_unit->output(a, 0);
00106 cout << endl;
00107 }
00108 else {
00109 ofstream outf(the_unit->output_file().c_str());
00110 output_context b = output_context(outf);
00111 the_unit->output(b, 0);
00112 outf << endl;
00113 }
00114 }
00115 }
00116 };
00117
00118 Phases Output_C("c-code", new output_c_phase());
00119
00123 class DismantleControlChangerPhase : public Phase {
00124 public:
00125
00126 void run() {
00127 unit_list_p n;
00128
00129
00130 for (n=CBZ::Program.begin(); n != CBZ::Program.end(); n++)
00131 Dismantle::dismantle_control(*n);
00132 }
00133 };
00134
00135 Phases dismantle_control_phase("dismantle-control",
00136 new DismantleControlChangerPhase());
00137
00141 class DismantleChangerPhase : public Phase {
00142 public:
00143
00144 void run() {
00145 unit_list_p n;
00146
00147
00148 for (n=CBZ::Program.begin(); n != CBZ::Program.end(); n++)
00149 Dismantle::dismantle(*n);
00150 }
00151 };
00152
00153 Phases dismantle_phase("dismantle", new DismantleChangerPhase());
00154
00158 class CfgPhase : public Phase {
00159 public:
00160 void run() {
00161 unit_list_p n;
00162 for ( n = CBZ::Program.begin(); n != CBZ::Program.end(); n++ )
00163 cfg_changer::generate_cfg(*n);
00164 }
00165 };
00166
00167 Phases make_cfg_phase("cfg", new CfgPhase());
00168
00169
00170 class lirGenWalkerPhase: public Phase {
00171 public:
00172 void run() {
00173
00174 if (! CBZ::ArchInfo.is_valid()) {
00175 printf( "ERROR: Can't generate LIR - missing architecture specification file. specify with '-arch' option\n" );
00176 return;
00177 }
00178
00179
00180 for ( unit_list_p u = CBZ::Program.begin();
00181 u != CBZ::Program.end();
00182 u++ )
00183 Dismantle::dismantle(*u);
00184
00185
00186 lir_gen_walker lgw;
00187 unit_list_p u;
00188 for (u=CBZ::Program.begin(); u!=CBZ::Program.end(); u++){
00189 (*u) -> walk(lgw);
00190 }
00191
00192
00193
00194
00195 if (CBZ::NoRegAlloc) {
00196 dummy_reg_alloc_walker drw;
00197 unit_list_p u;
00198 for (u=CBZ::Program.begin(); u!=CBZ::Program.end(); u++){
00199 (*u) -> walk(drw);
00200 }
00201 }
00202 }
00203 };
00204
00205 Phases lir_gen_walker_phase ("lir", new lirGenWalkerPhase());
00206
00207
00208 class lirFlowWalkerPhase: public Phase {
00209 public:
00210 void run() {
00211
00212
00213 lir_flow_walker lfw;
00214 unit_list_p u;
00215 for (u=CBZ::Program.begin(); u!=CBZ::Program.end(); u++){
00216 (*u) -> walk(lfw);
00217 }
00218 }
00219 };
00220
00221 Phases lir_flow_walker_phase ("lir_flow_walker", new lirFlowWalkerPhase());
00222
00223
00224 class regAllocPhase: public Phase {
00225 public:
00226 void run() {
00227
00228
00229 if (! CBZ::ArchInfo.is_valid()) {
00230 printf( "ERROR: Can't run register allocator - missing architecture specification file. specify with '-arch' option\n" );
00231 return;
00232 }
00233
00234
00235 RegAllocWalker ra;
00236 unit_list_p u;
00237 for (u=CBZ::Program.begin(); u!=CBZ::Program.end(); u++){
00238 (*u) -> walk(ra);
00239 }
00240 }
00241 };
00242
00243 Phases reg_alloc_phase("reg_alloc", new regAllocPhase());
00244
00245
00246 class asmGenWalkerPhase: public Phase {
00247 public:
00248 void run() {
00249
00250
00251 if (! CBZ::ArchInfo.is_valid()) {
00252 printf( "ERROR: Can't run asm generator - missing architecture specification file. specify with '-arch' option\n" );
00253 return;
00254 }
00255
00256
00257 asm_gen_walker asm_gen;
00258 unit_list_p u;
00259 for (u=CBZ::Program.begin(); u!=CBZ::Program.end(); u++){
00260 (*u) -> walk(asm_gen);
00261 }
00262 }
00263 };
00264
00265 Phases asm_gen_phase("asm", new asmGenWalkerPhase());
00266
00270 class DeadPhase : public Phase {
00271 public:
00272 void run (void) {
00273 for (unit_list_p u = CBZ::Program.begin() ; u != CBZ::Program.end() ; u++)
00274 {
00275 cfg_changer::generate_cfg(*u);
00276
00277 deadCodeEliminationChanger dcec;
00278 (*u)->change(dcec);
00279 }
00280 }
00281 };
00282
00283 Phases deadPhase("dead", new DeadPhase());
00284
00288 class ListPhase : public Phase {
00289 public:
00290 void run (void) {
00291 phase_vec * pv = Phases::phases();
00292 for (phase_vec_p p = pv->begin() ; p != pv->end() ; p++) {
00293 Phase_entry * pe = (Phase_entry *) (*p);
00294 pe->print();
00295 }
00296 }
00297 };
00298
00299 Phases listPhase("listphases", new ListPhase(),
00300 "This phase lists currently registered phases.");
00301
00305 class TreeCheckerPhase : public Phase {
00306 private:
00307 bool _verbose;
00308 bool _warning;
00309 public:
00310 void run (void) {
00311
00312 for (unit_list_p u = CBZ::Program.begin() ; u != CBZ::Program.end() ; u++)
00313 {
00314
00315 TreeChecker tcw(_verbose, _warning);
00316 (*u)->walk(tcw);
00317 }
00318 }
00319
00320 void get_flags(str_list_p & arg) {
00321 string opt = *arg;
00322 if(strncmp("verbose:", opt.c_str(), 8) == 0) {
00323 _verbose = true;
00324 opt.erase(0,8);
00325 arg++;
00326 }
00327 else if(strncmp("warning:", opt.c_str(), 8) == 0) {
00328 _warning = true;
00329 opt.erase(0,8);
00330 arg++;
00331 }
00332 };
00333
00334 void usage () {
00335 cout << " It can be used to verify the AST both before and after running "
00336 << "the dismantler." << endl
00337 << " If this phase is run after the code has been dismantled, "
00338 << "then it will" << endl
00339 << " additionally check that only valid nodes appear in the AST."
00340 << endl
00341 << " usage: cbz -check-ast [verbose: | warning:] files..." << endl
00342 << " verbose: Output all messages about what this phase is doing"
00343 << endl
00344 << " warning: Output warning and informative messages" << endl;
00345 }
00346 };
00347
00348 Phases treeCheckerPhase("check-ast", new TreeCheckerPhase(),
00349 "This phase checks that the AST is indeed a tree.");
00350
00351 Phases fiPhase("fi", new fi());
00352
00353
00354
00355
00356
00357
00358
00359 str_list * process_flags(int argc, char *argv[])
00360 {
00361 str_list * args = new str_list();
00362 str_list * pre = new str_list();
00363 str_list_p p, pn;
00364
00365 for (int i = 1; i < argc; ++i) {
00366 char s[1000];
00367 int k=0, j=0;
00368
00369
00370 for(;argv[i][j]; j++) {
00371 if (argv[i][j] == '"')
00372 s[k++] = '\\';
00373 s[k++] = argv[i][j];
00374 }
00375 s[k] = 0;
00376 args->push_back(string(s));
00377 }
00378
00379 p = args->begin();
00380
00381 while (p != args->end()) {
00382
00383
00384
00385
00386 if (*p == "--") {
00387 ++p;
00388 pre->splice(pre->begin(), * args, p, args->end());
00389 break;
00390 }
00391
00392
00393
00394 if (Phases::phase_flag(p)) {
00395
00396 }
00397 else if (*p == "-ansi") {
00398 CBZ::ANSIOnly = true;
00399 ++p;
00400 }
00401 else if (*p == "-format") {
00402 CBZ::FormatReadably = true;
00403 ++p;
00404 }
00405 else if (*p == "-no-pre") {
00406 CBZ::Preprocess = false;
00407 ++p;
00408 }
00409 else if (*p == "-pre") {
00410 CBZ::ShowPreprocess = true;
00411 ++p;
00412 }
00413 else if (*p == "-gcc") {
00414 CBZ::GCCisms = true;
00415 ++p;
00416 }
00417 else if (*p == "-P") {
00418 ++p;
00419 CBZ::preproc = *p;
00420 ++p;
00421 }
00422 else if (*p == "-suff") {
00423 ++p;
00424 CBZ::output_suffix = *p;
00425 ++p;
00426 }
00427 else if (*p == "-W") {
00428 ++p;
00429 CBZ::WarningLevel = atoi((*p).c_str());
00430 if (CBZ::WarningLevel < 0 || CBZ::WarningLevel > 5) {
00431 cerr << "Error: Warning level must be between 0 and 5." << endl;
00432 CBZ::WarningLevel = 4;
00433 } else
00434 ++p;
00435 }
00436 else if (*p == "-Wall") {
00437 CBZ::WarningLevel = 5;
00438 ++p;
00439 }
00440 else if (*p == "-arch") {
00441 ++p;
00442 string spec_file = *p;
00443 ++p;
00444
00445
00446 if (! CBZ::ArchInfo.load_arch_info(spec_file.c_str())) {
00447 cerr << "Error: Can't read architecture specification file '"
00448 << spec_file << "'." << endl;
00449 return NULL;
00450 }
00451 }
00452 else if (*p == "-noreg") {
00453 CBZ::NoRegAlloc = true;
00454 ++p;
00455 }
00456 else {
00457
00458 string output_file;
00459
00460 if (*p == "(stdin)")
00461 output_file = string("(stdout)");
00462 else {
00463 output_file = (*p);
00464 int suff_pos = output_file.rfind(CBZ::input_suffix);
00465 if (suff_pos >= 0 && suff_pos < (int)(*p).length())
00466 output_file.replace(suff_pos,
00467 CBZ::input_suffix.length(),
00468 CBZ::output_suffix);
00469 else
00470 output_file = string("(stdout)");
00471 }
00472
00473 CBZ::Program.push_back(new unitNode(*p, output_file));
00474 ++p;
00475 }
00476 }
00477
00478
00479
00480 if (CBZ::preproc.empty()) {
00481 if (CBZ::ANSIOnly)
00482 CBZ::preproc = CBZ::ansi_preproc;
00483 else if (CBZ::GCCisms)
00484 CBZ::preproc = CBZ::gcc_preproc;
00485 else
00486 CBZ::preproc = CBZ::default_preproc;
00487 }
00488
00489
00490
00491 return pre;
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 int main(int argc, char * argv[])
00547 {
00548
00549
00550 Operators::init();
00551
00552
00553
00554 CBZ::cpp_flags = process_flags(argc, argv);
00555 if ( ! CBZ::cpp_flags )
00556 return 1;
00557
00558
00559
00560 for (unit_list_p p = CBZ::Program.begin();
00561 p != CBZ::Program.end();
00562 ++p)
00563 (*p)->parse(CBZ::cpp_flags);
00564
00565
00566
00567 Phases::run_all();
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578 }
00579