| Polaris: Statement.cc Source File |
|
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members
Statement.ccGo to the documentation of this file.00001 /// 00002 #ifdef POLARIS_GNU_PRAGMAS 00003 #pragma implementation "Statement.h" 00004 #pragma implementation "AllocateStmt.h" 00005 #pragma implementation "ArithmeticIfStmt.h" 00006 #pragma implementation "AssignStmt.h" 00007 #pragma implementation "AssignedGotoStmt.h" 00008 #pragma implementation "AssignmentStmt.h" 00009 #pragma implementation "BlockEntryStmt.h" 00010 #pragma implementation "BlockExitStmt.h" 00011 #pragma implementation "CallStmt.h" 00012 #pragma implementation "ComputedGotoStmt.h" 00013 #pragma implementation "DeallocateStmt.h" 00014 #pragma implementation "DirectiveStmt.h" 00015 #pragma implementation "DoStmt.h" 00016 #pragma implementation "ElseIfStmt.h" 00017 #pragma implementation "ElseStmt.h" 00018 #pragma implementation "EndDoStmt.h" 00019 #pragma implementation "EndIfStmt.h" 00020 #pragma implementation "EntryStmt.h" 00021 #pragma implementation "FlowEntryStmt.h" 00022 #pragma implementation "FlowExitStmt.h" 00023 #pragma implementation "GotoStmt.h" 00024 #pragma implementation "IOStmt.h" 00025 #pragma implementation "IfStmt.h" 00026 #pragma implementation "ImpliedGotoStmt.h" 00027 #pragma implementation "LabelStmt.h" 00028 #pragma implementation "NullifyStmt.h" 00029 #pragma implementation "PauseStmt.h" 00030 #pragma implementation "ReturnStmt.h" 00031 #pragma implementation "StmtPointer.h" 00032 #pragma implementation "StopStmt.h" 00033 #pragma implementation "WhileStmt.h" 00034 #endif 00035 /// 00036 #include <stream.h> 00037 #include <ctype.h> 00038 #include <stdlib.h> 00039 00040 #include "../BinRep.h" 00041 #include "../Collection/Iterator.h" 00042 #include "../Collection/KeyIterator.h" 00043 #include "../Collection/List.h" 00044 #include "../Dictionary.h" 00045 #include "../Directive/Assertion.h" 00046 #include "../Directive/StringAssertion.h" 00047 #include "../Directive/Assertion.all.h" 00048 #include "../Directive/AssertionList.h" 00049 #include "../Directive/Directive.h" 00050 #include "../ExprTable.h" 00051 #include "../Expression/Expression.h" 00052 #include "../Expression/FormatExpr.h" 00053 #include "../Expression/LabelExpr.h" 00054 #include "../Expression/StmtLabelExpr.h" 00055 #include "../ProgramUnit.h" 00056 #include "../String.h" 00057 #include "../Symbol/Symbol.h" 00058 #include "../SymbolAccessMap.h" 00059 #include "../SymbolAccessRefMap.h" 00060 #include "../Symtab.h" 00061 #include "../VDL.h" 00062 #include "../VoidPtrDef.h" 00063 #include "../wide_output.h" 00064 #include "../debug.h" 00065 #include "../utilities/switches_util.h" 00066 00067 #include "AllocateStmt.h" 00068 #include "ArithmeticIfStmt.h" 00069 #include "AssignStmt.h" 00070 #include "AssignedGotoStmt.h" 00071 #include "AssignmentStmt.h" 00072 #include "BlockEntryStmt.h" 00073 #include "BlockExitStmt.h" 00074 #include "CallStmt.h" 00075 #include "ComputedGotoStmt.h" 00076 #include "DeallocateStmt.h" 00077 #include "DirectiveStmt.h" 00078 #include "DoStmt.h" 00079 #include "ElseIfStmt.h" 00080 #include "ElseStmt.h" 00081 #include "EndDoStmt.h" 00082 #include "EndIfStmt.h" 00083 #include "EntryStmt.h" 00084 #include "FlowEntryStmt.h" 00085 #include "FlowExitStmt.h" 00086 #include "GotoStmt.h" 00087 #include "IOStmt.h" 00088 #include "IfStmt.h" 00089 #include "ImpliedGotoStmt.h" 00090 #include "LabelStmt.h" 00091 #include "NullifyStmt.h" 00092 #include "PauseStmt.h" 00093 #include "ReturnStmt.h" 00094 #include "StmtPointer.h" 00095 #include "StopStmt.h" 00096 #include "WhileStmt.h" 00097 #include "../Collection/RefMap.h" 00098 00099 #include "../macros.h" 00100 #include "../p-assert.h" 00101 00102 template class Map<Statement,StringElem>; 00103 template class RefMap<Statement,ProgramUnit>; 00104 template class TypedBaseMap<Statement,StringElem>; 00105 template class TypedBaseRefMap<Statement,ProgramUnit>; 00106 template class ProtoMap<Statement,StringElem>; 00107 template class ProtoRefMap<Statement,ProgramUnit>; 00108 template class KeyIterator<Statement,ProgramUnit>; 00109 template class KeyIterator<Statement,StringElem>; 00110 00111 /// NextEntry functions 00112 00113 void 00114 NextEntry::print(ostream & o) const 00115 { 00116 o << "<" << _tag << ", " << _next << ">"; 00117 } 00118 00119 NextEntry::~NextEntry() 00120 { 00121 /// Nothing to do 00122 } 00123 00124 int 00125 NextEntry::structures_OK() const 00126 { 00127 p_assert(0, "ERROR"); 00128 return 1; 00129 } 00130 00131 Definition * 00132 NextEntry::definition_clone() const 00133 { 00134 p_assert(0, "ERROR"); 00135 return 0; 00136 } 00137 00138 00139 /// STATEMENT PRINTING UTILLITY FUNCTIONS 00140 00141 /// Print a list of statements in FORTRAN form 00142 /// --Avoid printing the main entry point statement, which is 00143 /// --printed via print_main_entry_stmt(). 00144 00145 void 00146 print_stmt_list(ostream &o, Iterator<Statement> &iter) 00147 { 00148 int indent = 0; 00149 00150 if (!(iter.valid())) 00151 return; 00152 00153 int print_accreg = switch_value("print_accreg"); 00154 00155 if (iter.current().stmt_class() == FLOW_ENTRY_STMT) { 00156 00157 /// ... _ 00158 Statement &s = iter.current(); 00159 for (Iterator<StringElem> pre_iter = s.pre_directives(); 00160 pre_iter.valid(); ++pre_iter) { 00161 wide_output( o, 0 ); 00162 o << (String) pre_iter.current() << endl; 00163 } 00164 for (Iterator<StringElem> post_iter = s.post_directives(); 00165 post_iter.valid(); ++post_iter) { 00166 wide_output( o, 0 ); 00167 o << (String) post_iter.current() << endl; 00168 } 00169 /// ... _ FLOW_ENTRY directives are printed. 00170 00171 ++iter; 00172 00173 if (!(iter.valid())) 00174 return; 00175 00176 if (iter.current().stmt_class() == ENTRY_STMT) { 00177 /// ... Avoid this ENTRY_STMT 00178 if (print_accreg) { 00179 ((EntryStmt &)iter.current()).write_access_summary( o ); 00180 } 00181 ++iter; 00182 } 00183 } 00184 00185 for (; iter.valid(); ++iter) { 00186 Statement &s = iter.current(); 00187 00188 if (s.stmt_class() == BLOCK_ENTRY_STMT) { 00189 wide_output( o, 0 ); 00190 o << "CSRD$ BEGIN BLOCK" << endl; 00191 } 00192 00193 for (Iterator<StringElem> pre_iter = s.pre_directives(); 00194 pre_iter.valid(); ++pre_iter) { 00195 wide_output( o, 0 ); 00196 o << (String) pre_iter.current() << endl; 00197 } 00198 00199 if (s.stmt_class() == ENDDO_STMT) 00200 pop_wide_loop(); 00201 else if (s.stmt_class() == WHILE_STMT) 00202 push_wide_loop( 0 ); 00203 else if (s.stmt_class() == DO_STMT) { 00204 DoStmt & ds = (DoStmt &) s; 00205 push_wide_loop( ds.target_label() ); 00206 } 00207 00208 switch (s.stmt_class()) { 00209 case IMPLIED_GOTO_STMT: 00210 case FLOW_ENTRY_STMT: 00211 case FLOW_EXIT_STMT: 00212 case BLOCK_ENTRY_STMT: 00213 case BLOCK_EXIT_STMT: 00214 break; 00215 default: 00216 wide_output( o, s.line() ); 00217 break; 00218 } 00219 00220 s.write(o, indent); 00221 00222 if (print_accreg) { 00223 s.write_access_table( o ); 00224 } 00225 00226 for (Iterator<StringElem> post_iter = s.post_directives(); 00227 post_iter.valid(); ++post_iter) { 00228 wide_output( o, 0 ); 00229 o << (String) post_iter.current() << endl; 00230 } 00231 00232 if (s.stmt_class() == BLOCK_EXIT_STMT) { 00233 wide_output( o, 0 ); 00234 o << "CSRD$ END BLOCK" << endl; 00235 } 00236 } 00237 } 00238 00239 /// Print the tags of the statements in the list 00240 00241 void 00242 print_stmt_tags(ostream & o, Iterator<Statement> &iter) 00243 { 00244 if (iter.valid()) { 00245 if (iter.current_valid()) 00246 o << iter.current().tag(); 00247 else 00248 o << "<INVALID>"; 00249 00250 for (iter.next(); iter.valid(); iter.next()) { 00251 if (iter.current_valid()) 00252 o << ", " << iter.current().tag(); 00253 else 00254 o << "<INVALID>"; 00255 } 00256 } 00257 } 00258 00259 /// Print the labels of the statements in the list 00260 00261 void 00262 print_target_labels(ostream & o, Iterator<Statement> &iter) 00263 { 00264 if (iter.valid()) { 00265 if (! iter.current_valid()) 00266 o << "<INVALID>"; 00267 else { 00268 p_assert(iter.current().stmt_class() == LABEL_STMT, 00269 "not a label"); 00270 o << iter.current().value(); 00271 } 00272 00273 for (iter.next(); iter.valid(); iter.next()) { 00274 if (! iter.current_valid()) 00275 o << "<INVALID>"; 00276 else { 00277 p_assert(iter.current().stmt_class() == LABEL_STMT, 00278 "not a label"); 00279 o << ", " << iter.current().value(); 00280 } 00281 } 00282 } 00283 } 00284 00285 void 00286 print_expr_list(ostream &o, Iterator<Expression> &iter) 00287 { 00288 if (iter.valid()) { 00289 if (iter.current_valid()) 00290 o << iter.current(); 00291 else 00292 o << "<INVALID>"; 00293 } 00294 00295 for (iter.next(); iter.valid(); iter.next()) { 00296 o << ", " ; 00297 00298 if (iter.current_valid()) 00299 o << iter.current(); 00300 else 00301 o << "<INVALID>"; 00302 } 00303 } 00304 00305 00306 00307 void 00308 print_stmt_list(ostream & o, const RefSet<Statement> &stmts) 00309 { 00310 Iterator<Statement> iter = stmts; 00311 print_stmt_list( o, iter ); 00312 } 00313 00314 void 00315 print_stmt_list(ostream & o, const RefList<Statement> &stmts) 00316 { 00317 Iterator<Statement> iter = stmts; 00318 print_stmt_list( o, iter ); 00319 } 00320 00321 void 00322 print_stmt_list(ostream & o, const List<Statement> &stmts) 00323 { 00324 Iterator<Statement> iter = stmts; 00325 print_stmt_list( o, iter ); 00326 } 00327 00328 00329 00330 void 00331 print_stmt_tags(ostream & o, const RefSet<Statement> &stmts) 00332 { 00333 Iterator<Statement> iter = stmts; 00334 print_stmt_tags( o, iter ); 00335 } 00336 00337 void 00338 print_stmt_tags(ostream & o, const RefList<Statement> &stmts) 00339 { 00340 Iterator<Statement> iter = stmts; 00341 print_stmt_tags( o, iter ); 00342 } 00343 00344 void 00345 print_stmt_tags(ostream & o, const List<Statement> &stmts) 00346 { 00347 Iterator<Statement> iter = stmts; 00348 print_stmt_tags( o, iter ); 00349 } 00350 00351 00352 00353 void 00354 print_target_labels(ostream & o, RefSet<Statement> &stmts) 00355 { 00356 Iterator<Statement> iter = stmts; 00357 print_target_labels( o, iter ); 00358 } 00359 00360 void 00361 print_target_labels(ostream & o, RefList<Statement> &stmts) 00362 { 00363 Iterator<Statement> iter = stmts; 00364 print_target_labels( o, iter ); 00365 } 00366 00367 void 00368 print_target_labels(ostream & o, List<Statement> &stmts) 00369 { 00370 Iterator<Statement> iter = stmts; 00371 print_target_labels( o, iter ); 00372 } 00373 00374 00375 00376 00377 void 00378 print_expr_list(ostream &o, const RefSet<Expression> &exprs) 00379 { 00380 Iterator<Expression> iter = exprs; 00381 print_expr_list( o, iter ); 00382 } 00383 00384 void 00385 print_expr_list(ostream &o, const RefList<Expression> &exprs) 00386 { 00387 Iterator<Expression> iter = exprs; 00388 print_expr_list( o, iter ); 00389 } 00390 00391 void 00392 print_expr_list(ostream &o, const List<Expression> &exprs) 00393 { 00394 Iterator<Expression> iter = exprs; 00395 print_expr_list( o, iter ); 00396 } 00397 00398 00399 00400 static void 00401 fortran_indent( ostream &o, int indent ) 00402 { 00403 while (indent-- > 0) 00404 o << " "; 00405 } 00406 00407 00408 00409 00410 00411 /// WE SHOULDN\'T NEED THIS 00412 00413 void 00414 print_string_list(ostream & o, const List<StringElem> & strings) 00415 { 00416 Iterator<StringElem>iter = strings; 00417 if (iter.valid()) 00418 o << iter.current(); 00419 for (iter.next(); iter.valid(); iter.next()) 00420 o << ", " << iter.current(); 00421 } 00422 00423 00424 00425 s_control_type::s_control_type (String & key, Expression *expr) 00426 : keyword(key) 00427 { 00428 this->expr.make_static_list(1); 00429 this->expr.modify(0, expr); 00430 } 00431 00432 s_control_type::s_control_type() 00433 { 00434 this->expr.make_static_list(1); 00435 } 00436 00437 s_control_type::~s_control_type() 00438 { 00439 this->expr.clear(); 00440 } 00441 00442 Listable * 00443 s_control_type::listable_clone() const 00444 { 00445 s_control_type *hold = new s_control_type; 00446 00447 hold->keyword = keyword; 00448 hold->expr = this->expr; 00449 00450 return hold; 00451 } 00452 00453 int 00454 s_control_type::structures_OK() const 00455 { 00456 p_abort("can not call structures_OK() on s_control_type"); 00457 00458 return 1; 00459 } 00460 00461 ostream & 00462 operator << (ostream & o, const s_control_type & sct) 00463 { 00464 sct.print(o); 00465 00466 return o; 00467 } 00468 00469 00470 void 00471 s_control_type::print(ostream & o) const 00472 { 00473 o << "["; 00474 o << keyword << ", " << this->expr[0]; 00475 o << "]"; 00476 } 00477 00478 void 00479 s_control_type::write(ostream & o) const 00480 { 00481 o << keyword << " = " << this->expr[0]; 00482 } 00483 00484 00485 00486 /// //// OTHER HELPER FUNCTIONS 00487 00488 void 00489 StmtPointer::_setptrs(Dictionary<VoidPtrDef> & NOTUSED(tags), 00490 const FormatDB & NOTUSED(formats)) 00491 { 00492 cerr << "StmtPointer::_setptrs: Method inappropriate\n"; 00493 } 00494 00495 int 00496 StmtPointer::structures_OK() const 00497 { 00498 return 1; 00499 } 00500 00501 void 00502 StmtPointer::exchange_convert( VDL &vdl ) 00503 { 00504 Statement::exchange_convert( vdl ); 00505 00506 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 00507 00508 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 00509 00510 BinRep *br = new BinRep( new List<BinRep> ); 00511 br->to_tuple().ins_last( new BinRep( "st" )); 00512 br->to_tuple().ins_last( new BinRep( "STMT_PTR" )); 00513 S.ins( br ); 00514 } 00515 00516 void 00517 StmtPointer::convert(BinRep & NOTUSED(stmt), 00518 ExprTable & NOTUSED(etable), 00519 Symtab & NOTUSED(symtab), 00520 const NamelistDict & NOTUSED(namelists), 00521 const FormatDB & NOTUSED(formats), 00522 Dictionary<NextEntry> * NOTUSED(next_table)) 00523 { 00524 p_abort( "StmtPointer::convert: Can't convert a StmtPtr" ); 00525 } 00526 00527 StmtPointer::StmtPointer(const char *l) 00528 : Statement(l, STMT_PTR) 00529 { 00530 /// ... nothing to do 00531 } 00532 00533 StmtPointer::StmtPointer(const StmtPointer & stmt) 00534 : Statement(stmt.tag(), STMT_PTR) 00535 { 00536 copy_base(stmt); 00537 } 00538 00539 StmtPointer & 00540 StmtPointer::operator = (const StmtPointer & stmt) 00541 { 00542 copy_base(stmt); 00543 return *this; 00544 } 00545 00546 Statement * 00547 StmtPointer::clone() const 00548 { 00549 return new StmtPointer(*this); 00550 } 00551 00552 StmtPointer::~StmtPointer() 00553 { 00554 /// ... nothing to do 00555 } 00556 00557 void 00558 StmtPointer::fortran_write(ostream & NOTUSED(o), 00559 int & NOTUSED(indent), 00560 char * NOTUSED(type)) const 00561 { 00562 /// ... nothing to do 00563 } 00564 00565 void 00566 StmtPointer::print_debug(ostream & o, int NOTUSED(debug)) const 00567 { 00568 o << "PTR TO " << _tag; 00569 } 00570 00571 Statement * 00572 temp_stmt_ptr(BinRep & name) 00573 { 00574 p_assert(name.is_string(), "not a string"); 00575 00576 String name_str; 00577 name.to_string(name_str); 00578 00579 return (new StmtPointer(name_str)); 00580 } 00581 00582 /// Given a BinRep (which should be a set of strings) and a list 00583 /// of Statement *, insert dummy statements into the list with the 00584 /// tagss indicated in the set. Stype is used for error messages. 00585 00586 void 00587 convert_stmt_list(BinRep & set, List<Statement> &slist, const char *stype) 00588 { 00589 if (set.is_set()) { 00590 for (Iterator<BinRep> iter = set.to_set(); iter.valid(); ++iter) { 00591 BinRep & st_name = iter.current(); 00592 if (st_name.is_string()) 00593 slist.ins_last( temp_stmt_ptr(st_name) ); 00594 else { 00595 cerr << stype << "::convert:convert_stmt_list: " 00596 << "non-string encountered" << endl; 00597 p_abort( "(see above message)" ); 00598 } 00599 } 00600 } 00601 else if (set.is_tuple()) { 00602 for (Iterator<BinRep> iter = set.to_tuple(); iter.valid(); ++iter) { 00603 BinRep & st_name = iter.current(); 00604 if (st_name.is_string()) 00605 slist.ins_last( temp_stmt_ptr(st_name) ); 00606 else { 00607 cerr << stype << "::convert:convert_stmt_list: " 00608 << "non-string encountered" << endl; 00609 p_abort( "(see above message)" ); 00610 } 00611 } 00612 } 00613 else { 00614 cerr << "convert_stmt_list called with non-list in " 00615 << stype << ":convert" << endl; 00616 p_abort( "(see above message)" ); 00617 } 00618 } 00619 00620 /// Given a BinRep (which should be a set of strings) and a list 00621 /// of Statement *, insert dummy statements into the list with the 00622 /// tags indicated in the set. Stype is used for error messages. 00623 00624 void 00625 convert_stmt_list(BinRep &set, RefList<Statement> &sreflist, 00626 List<Statement> &slist, const char *stype) 00627 { 00628 if (set.is_set()) { 00629 for (Iterator<BinRep> iter = set.to_set(); iter.valid(); ++iter) { 00630 BinRep & st_name = iter.current(); 00631 if (st_name.is_string()) 00632 slist.ins_last(temp_stmt_ptr(st_name)); 00633 else { 00634 cerr << stype << "::convert:convert_stmt_list: " 00635 << "non-string encountered" << endl; 00636 p_abort( "(see above message)" ); 00637 } 00638 } 00639 for (Iterator<Statement> siter = slist; siter.valid(); ++siter) 00640 sreflist.ins_last(siter.current()); 00641 } 00642 else if (set.is_tuple()) { 00643 for (Iterator<BinRep> iter = set.to_tuple(); iter.valid(); ++iter) { 00644 BinRep & st_name = iter.current(); 00645 if (st_name.is_string()) 00646 slist.ins_last(temp_stmt_ptr(st_name)); 00647 else { 00648 cerr << stype << "::convert:convert_stmt_list: " 00649 << "non-string encountered" << endl; 00650 p_abort( "(see above message)" ); 00651 } 00652 } 00653 for (Iterator<Statement> siter = slist; siter.valid(); ++siter) 00654 sreflist.ins_last(siter.current()); 00655 } 00656 else { 00657 cerr << "convert_stmt_list called with non-list in " << stype 00658 << ":convert" << endl; 00659 p_abort( "(see above message)" ); 00660 } 00661 } 00662 00663 void 00664 convert_stmt_list(BinRep & set, RefSet<Statement> & srefset, 00665 List<Statement> &slist, const char *stype) 00666 { 00667 if (set.is_set()) { 00668 for (Iterator<BinRep> iter = set.to_set(); iter.valid(); ++iter) { 00669 BinRep & st_name = iter.current(); 00670 if (st_name.is_string()) 00671 slist.ins_last(temp_stmt_ptr(st_name)); 00672 else { 00673 cerr << stype << "::convert:convert_stmt_list: " 00674 << "non-string encountered" << endl; 00675 p_abort( "(see above message)" ); 00676 } 00677 } 00678 for (Iterator<Statement> siter = slist; siter.valid(); ++siter) 00679 srefset.ins(siter.current()); 00680 } 00681 else if (set.is_tuple()) { 00682 for (Iterator<BinRep> iter = set.to_tuple(); iter.valid(); ++iter) { 00683 BinRep & st_name = iter.current(); 00684 if (st_name.is_string()) 00685 slist.ins_last(temp_stmt_ptr(st_name)); 00686 else { 00687 cerr << stype << "::convert:convert_stmt_list: " 00688 << "non-string encountered" << endl; 00689 p_abort( "(see above message)" ); 00690 } 00691 } 00692 for (Iterator<Statement> siter = slist; siter.valid(); ++siter) 00693 srefset.ins(siter.current()); 00694 } 00695 else { 00696 cerr << "convert_stmt_list called with non-list in " << stype 00697 << ":convert" << endl; 00698 p_abort( "(see above message)" ); 00699 } 00700 } 00701 00702 /// Convert a binstr from a set of entries into the expression table 00703 /// into a list of pointers to expressions. 00704 00705 void 00706 convert_expr_list(BinRep &entry_set, RefList<Expression> &exprs, 00707 ExprTable &expr_table, const char *caller) 00708 { 00709 for (Iterator<BinRep> iter = entry_set.to_set(); iter.valid(); ++iter) { 00710 BinRep & entry = iter.current(); 00711 if (entry.is_integer()) 00712 exprs.ins_last(*expr_table[entry.to_integer()]); 00713 else { 00714 cerr << caller 00715 << ":convert_expr_list: expression set contains non-int\n"; 00716 p_abort( "(see above message)" ); 00717 } 00718 } 00719 } 00720 00721 /// Convert a binstr from a set of entries into the expression table 00722 /// into a list of pointers to expressions. 00723 00724 void 00725 convert_expr_list(BinRep &entry_set, RefSet<Expression> &exprs, 00726 List<Expression> &exprs_list, 00727 ExprTable &expr_table, const char *caller) 00728 { 00729 for (Iterator<BinRep> iter = entry_set.to_set(); iter.valid(); ++iter) { 00730 BinRep & entry = iter.current(); 00731 if (entry.is_integer()) 00732 exprs_list.ins_last(expr_table[entry.to_integer()]); 00733 else { 00734 cerr << caller 00735 << ":convert_expr_list: expression set contains non-int\n"; 00736 p_abort( "(see above message)" ); 00737 } 00738 } 00739 for (Iterator<Expression> eiter = exprs_list; eiter.valid(); ++eiter) 00740 exprs.ins(eiter.current()); 00741 } 00742 00743 /// Convert a binstr which is a tuple of strings into a list 00744 00745 void 00746 convert_string_list(BinRep & string_tup, List<StringElem> &strings, 00747 const char *caller) 00748 { 00749 for (Iterator<BinRep> iter = string_tup.to_tuple(); iter.valid(); ++iter) { 00750 BinRep & str = iter.current(); 00751 if (!str.is_string()) { 00752 cerr << caller 00753 << ":convert_string_list: set contains non-string\n"; 00754 p_abort( "(see above message)" ); 00755 } 00756 else { 00757 StringElem *holder_str = new StringElem; 00758 str.to_string(*holder_str); 00759 strings.ins_last(holder_str); 00760 } 00761 } 00762 } 00763 00764 /// Convert a binstr which is a tuple of set assertions into a list 00765 00766 void 00767 convert_assert_list(BinRep & binstr, 00768 List<Assertion> & assertions, 00769 ExprTable & etable, 00770 const char * caller) 00771 { 00772 for (Iterator<BinRep> b_iter = binstr.to_tuple(); 00773 b_iter.valid(); ++b_iter) { 00774 BinRep & bp = b_iter.current(); 00775 if (! bp.is_set()) { 00776 cerr << caller 00777 << ":convert_assert_list: set contains non-map\n"; 00778 p_abort( "(see above message)" ); 00779 } 00780 else { 00781 String key; 00782 00783 bp["key"].to_string( key ); 00784 00785 Assertion *ap = 0; 00786 00787 if (key == "CSRD$PRIVATE" || key == "CSRD$ PRIVATE") 00788 ap = new AssertPrivate; 00789 else if (key == "CSRD$PARALLEL" || key == "CSRD$ PARALLEL") 00790 ap = new AssertParallel; 00791 else if (key == "CSRD$LASTVALUE" || key == "CSRD$LAST_VALUE" || 00792 key == "CSRD$ LASTVALUE" || key == "CSRD$ LAST_VALUE") 00793 ap = new AssertLastValue; 00794 else if (key == "CSRD$REDUCTION" || key == "CSRD$ REDUCTION") 00795 ap = new AssertReduction; 00796 00797 p_assert( ap, "unrecognized directive" ); 00798 00799 assertions.ins_last( ap ); 00800 00801 if (bp.find_ref("expr") != 0) { 00802 Expression *e = convert_expr(bp["expr"], etable, caller); 00803 00804 if (e->op() != COMMA_OP) 00805 ap->arg_list_guarded().ins_first( e ); 00806 else { 00807 for (Mutator<Expression> e_iter = e->arg_list(); 00808 e_iter.valid(); ++e_iter) 00809 ap->arg_list_guarded().ins_last( e_iter.pull() ); 00810 } 00811 } 00812 00813 } 00814 } 00815 } 00816 00817 /// Change stmt * from a StmtPtr dummy to a pointer to a real statement 00818 /// (except in the case where the Statement pointer points to a Format statement) 00819 00820 Boolean 00821 makeptr_ptr(Statement **ptr, Dictionary<VoidPtrDef> &tags) 00822 { 00823 p_assert((*ptr)->stmt_class() == STMT_PTR, "Object not a STMT_PTR"); 00824 00825 VoidPtrDef *v = tags.find_ref((*ptr)->tag()); 00826 00827 if (v == 0) { 00828 /// ... Check whether this is a Format statement (probably for an 00829 /// ... ASSIGN with a format label) 00830 00831 if ( ((*ptr)->tag())[0] != 'F' ) 00832 p_abort("Label not found in program"); 00833 00834 return False; 00835 } 00836 00837 Statement *holder = (Statement *) (tags[(*ptr)->tag()]).ptr_ref(); 00838 00839 delete *ptr; 00840 *ptr = holder; 00841 00842 return True; 00843 } 00844 00845 /// Determine if the statement expr1 = expr2 is in shape conformance 00846 /// (i.e. they are the same rank or expr2 is a scalar) 00847 Boolean shape_conformance(Expression & expr1, Expression & expr2) 00848 { 00849 return ((expr1.type().rank() == expr2.type().rank()) || 00850 (expr2.type().rank() == 0)); 00851 } 00852 00853 00854 00855 /// VARIOUS PRIVATE FUNCTIONS 00856 00857 void 00858 Statement::exchange_convert( VDL &vdl ) 00859 { 00860 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 00861 00862 Set<BinRep> & S = b->find_ref("statements")->to_set(); 00863 00864 BinRep *br = new BinRep( new List<BinRep> ); 00865 BinRep *bs = new BinRep( tag() ); 00866 BinRep *bt = new BinRep( new Set<BinRep> ); 00867 00868 br->to_tuple().ins_last( bs ); 00869 br->to_tuple().ins_last( bt ); 00870 00871 S.ins( br ); 00872 00873 Set<BinRep> & T = b->find_ref("statements")->find_ref( tag() )->to_set(); 00874 00875 /// ... Fill in the common fields. 00876 00877 if (next_ref() != 0) { 00878 br = new BinRep( new List<BinRep> ); 00879 br->to_tuple().ins_last( new BinRep( "next" )); 00880 br->to_tuple().ins_last( new BinRep( next_ref()->tag() )); 00881 T.ins( br ); 00882 } 00883 00884 if (prev_ref() != 0) { 00885 br = new BinRep( new List<BinRep> ); 00886 br->to_tuple().ins_last( new BinRep( "prev" )); 00887 br->to_tuple().ins_last( new BinRep( prev_ref()->tag() )); 00888 T.ins( br ); 00889 } 00890 00891 if (line() > 0) { 00892 br = new BinRep( new List<BinRep> ); 00893 br->to_tuple().ins_last( new BinRep( "line" )); 00894 br->to_tuple().ins_last( new BinRep( line() )); 00895 T.ins( br ); 00896 } 00897 00898 /// ... successors 00899 { 00900 br = new BinRep( new List<BinRep> ); 00901 br->to_tuple().ins_last( new BinRep( "successors" )); 00902 br->to_tuple().ins_last( new BinRep( new Set<BinRep> )); 00903 00904 for (Iterator<Statement> iter = succ(); iter.valid(); ++iter) 00905 br->to_tuple()[1].to_set().ins(new BinRep(iter.current().tag())); 00906 00907 T.ins( br ); 00908 } 00909 00910 /// ... predecessors 00911 { 00912 br = new BinRep( new List<BinRep> ); 00913 br->to_tuple().ins_last( new BinRep( "predecessors" )); 00914 br->to_tuple().ins_last( new BinRep( new Set<BinRep> )); 00915 00916 for (Iterator<Statement> iter = pred(); iter.valid(); ++iter) 00917 br->to_tuple()[1].to_set().ins(new BinRep(iter.current().tag())); 00918 00919 T.ins( br ); 00920 } 00921 00922 /// ... in_refs 00923 { 00924 br = new BinRep( new List<BinRep> ); 00925 br->to_tuple().ins_last( new BinRep( "in_refs" )); 00926 br->to_tuple().ins_last( new BinRep( new Set<BinRep> )); 00927 00928 for (Iterator<Expression> iter = in_refs(); iter.valid(); ++iter) { 00929 br->to_tuple()[1].to_set().ins( 00930 new BinRep( iter.current().exchange_expr(vdl))); 00931 } 00932 00933 T.ins( br ); 00934 } 00935 00936 /// ... out_refs 00937 { 00938 br = new BinRep( new List<BinRep> ); 00939 br->to_tuple().ins_last( new BinRep( "out_refs" )); 00940 br->to_tuple().ins_last( new BinRep( new Set<BinRep> )); 00941 00942 for (Iterator<Expression> iter = out_refs(); iter.valid(); ++iter) { 00943 br->to_tuple()[1].to_set().ins( 00944 new BinRep( iter.current().exchange_expr(vdl))); 00945 } 00946 00947 T.ins( br ); 00948 } 00949 00950 /// ... act_refs 00951 { 00952 br = new BinRep( new List<BinRep> ); 00953 br->to_tuple().ins_last( new BinRep( "act_refs" )); 00954 br->to_tuple().ins_last( new BinRep( new Set<BinRep> )); 00955 00956 for (Iterator<Expression> iter = act_refs(); iter.valid(); ++iter) { 00957 br->to_tuple()[1].to_set().ins( 00958 new BinRep( iter.current().exchange_expr(vdl))); 00959 } 00960 00961 T.ins( br ); 00962 } 00963 00964 if (outer_ref() != 0) { 00965 br = new BinRep( new List<BinRep> ); 00966 br->to_tuple().ins_last( new BinRep( "outer" )); 00967 br->to_tuple().ins_last( new BinRep( outer_ref()->tag() )); 00968 T.ins( br ); 00969 } 00970 00971 if (follow_ref() != 0) { 00972 br = new BinRep( new List<BinRep> ); 00973 br->to_tuple().ins_last( new BinRep( "follow" )); 00974 br->to_tuple().ins_last( new BinRep( follow_ref()->tag() )); 00975 T.ins( br ); 00976 } 00977 00978 if (lead_ref() != 0) { 00979 br = new BinRep( new List<BinRep> ); 00980 br->to_tuple().ins_last( new BinRep( "lead" )); 00981 br->to_tuple().ins_last( new BinRep( lead_ref()->tag() )); 00982 T.ins( br ); 00983 } 00984 } 00985 00986 Boolean 00987 Statement::marked_parallel() const 00988 { 00989 p_abort( "Statement::marked_parallel() called for " 00990 "wrong type of statement"); 00991 return false; 00992 } 00993 00994 Boolean 00995 Statement::marked_serial() const 00996 { 00997 p_abort( "Statement::marked_serial() called for " 00998 "wrong type of statement"); 00999 return false; 01000 } 01001 01002 RefSet<Symbol> * 01003 Statement::private_vars_ref() const 01004 /// Expressions from PRIVATE assertion 01005 { 01006 p_abort( "Statement::private_vars_ref() called for " 01007 "wrong type of statement"); 01008 return NULL; 01009 } 01010 01011 01012 void 01013 Statement::convert(BinRep & NOTUSED(stmt), 01014 ExprTable & NOTUSED(etable), 01015 Symtab & NOTUSED(symtab), 01016 const NamelistDict & NOTUSED(namelists), 01017 const FormatDB & NOTUSED(formats), 01018 Dictionary<NextEntry> * NOTUSED(next_table) ) 01019 { 01020 /// ... All of the subclasses define this, so this is never called 01021 01022 p_abort( "Statement::convert should never be called " 01023 "(should be over-ridden in all sub-classes)"); 01024 } 01025 01026 /// _add_act_refs: checks whether the given expression is a FUNCTION_CALL_OP. 01027 /// If so, sends the parameter list to add_act_params to check whether 01028 /// any of the parameters may be included in the _act_refs set. If not, 01029 /// the expression's subexpressions are checked for FUNCTION_CALL_OPs 01030 /// recursively. 01031 01032 void 01033 Statement::_add_act_refs (Expression &expr) 01034 { 01035 if (expr.op() == FUNCTION_CALL_OP) { 01036 if (expr.parameters_valid()) { 01037 _add_act_params (expr.parameters_guarded()); 01038 return; 01039 } 01040 } 01041 else { 01042 for (Iterator<Expression> iter = expr.arg_list(); iter.valid(); ++iter) 01043 _add_act_refs (iter.current()); 01044 } 01045 } 01046 01047 /// _add_act_params: called with COMMA_OP or OMEGA_OP which is the 01048 /// parameter list of a function call. Looks at each 01049 /// argument in turn. If it is a simple ID_OP, or ARRAY_REF_OP, 01050 /// then it is put in the _act_refs set. Otherwise, it is just 01051 /// checked for embedded FUNCTION_CALL_OPs. 01052 01053 void 01054 Statement::_add_act_params (Expression &expr) 01055 { 01056 p_assert (expr.op() == COMMA_OP || expr.op() == OMEGA_OP, 01057 "add_act_params called with non-COMMA_OP"); 01058 01059 if (expr.op() == OMEGA_OP) 01060 return; 01061 01062 for (Iterator<Expression> iter = expr.arg_list(); iter.valid(); ++iter) { 01063 if (iter.current().op() == ID_OP) 01064 _act_refs.ins (iter.current()); 01065 else if (iter.current().op() == ARRAY_REF_OP) { 01066 _act_refs.ins (iter.current()); 01067 _add_act_refs (iter.current().subscript()); 01068 } 01069 else if (iter.current().op() == SUBSTRING_OP) { 01070 _act_refs.ins (iter.current()); 01071 _add_act_refs (iter.current().bound()); 01072 } 01073 else { 01074 _add_act_refs (iter.current()); 01075 } 01076 } 01077 } 01078 01079 /// _add_ioread_sets: This routine adds the appropriate members 01080 /// to each of the _in_refs, _out_refs, and _act_refs sets. 01081 /// The expression which is the argument MUST be an element of 01082 /// the CommaExpr which is the _iolist of a READ statement. 01083 /// This is a special case, because each "top-level" ID or ARRAY 01084 /// is taken to be written-to (by the READ statement), while 01085 /// everything else is read from. One complication is due to 01086 /// the fact that a function call with parameters may appear in 01087 /// a subscript, or in the iteration space expressions, so these 01088 /// parameters must be added to the _out_refs. 01089 /// 01090 /// NOTE that the _out_refs are not complete after this is through- 01091 /// the caller still needs to add all members of the _act_refs 01092 /// set to the _out_refs set upon return. 01093 01094 void 01095 Statement::_add_ioread_sets (Expression &expr) 01096 { 01097 if (expr.op() == ID_OP) { 01098 _out_refs.ins (expr); 01099 return; 01100 } 01101 else if (expr.op() == ARRAY_REF_OP) { 01102 _out_refs.ins (expr); 01103 _add_in_refs (expr.subscript()); 01104 _add_act_refs (expr.subscript()); 01105 } 01106 else if (expr.op() == SUBSTRING_OP) { 01107 _out_refs.ins (expr); 01108 _add_in_refs (expr.bound()); 01109 _add_act_refs (expr.bound()); 01110 } 01111 else if (expr.op() == DO_OP) { 01112 _add_ioread_sets (expr.iolist()); 01113 _add_ioread_sets (expr.iterator()); 01114 } 01115 else if (expr.op() == EQUAL_OP) { 01116 _out_refs.ins (expr.index_id()); 01117 _add_in_refs (expr.iteration_space()); 01118 _add_act_refs(expr.iteration_space()); 01119 } 01120 else { 01121 for(Iterator<Expression> iter = expr.arg_list(); iter.valid(); ++iter) 01122 _add_ioread_sets (iter.current()); 01123 } 01124 } 01125 01126 /// _add_in_refs: Check the given expression to see whether it 01127 /// is an ID_OP, or an ARRAY_REF_OP. If so, add it to the _in_refs 01128 /// set. If not, whether it is a call of some kind, so as to 01129 /// carefully ignore the ID_OP of the name of the function, but 01130 /// still check the parameters. For all other types of expressions, 01131 /// recursively check them for IDs and ARRAY_REFs to add to the set. 01132 01133 void 01134 Statement::_add_in_refs (Expression &expr) 01135 { 01136 switch(expr.op()) { 01137 case ID_OP: 01138 _in_refs.ins(expr); 01139 break; 01140 case ARRAY_REF_OP: 01141 _in_refs.ins (expr); 01142 _add_in_refs (expr.subscript()); 01143 break; 01144 case SUBSTRING_OP: 01145 _in_refs.ins (expr); 01146 _add_in_refs (expr.bound()); 01147 break; 01148 case FUNCTION_CALL_OP: 01149 case INTRINSIC_CALL_OP: 01150 case LAMBDA_CALL_OP: 01151 /// ... Ignore the function_exp ID_OP !! 01152 if (expr.parameters_valid()) 01153 _add_in_refs (expr.parameters_guarded()); 01154 break; 01155 case GAMMA_OP: 01156 _add_in_refs (expr.gate()); 01157 /// ... Fall through into other psuedo-assignments 01158 case MU_OP: 01159 case ALPHA_OP: 01160 if (expr.parameters_valid()) 01161 _add_in_refs (expr.parameters_guarded()); 01162 break; 01163 case EQUAL_OP: 01164 /// ... Ignore the index_id_expression ID_OP !! (this is written) 01165 _add_in_refs (expr.iteration_space()); 01166 break; 01167 default: 01168 for (Iterator<Expression> iter = expr.arg_list(); iter.valid(); ++iter) 01169 _add_in_refs (iter.current()); 01170 } 01171 } 01172 01173 /// _add_out_refs: This is only called when we are working with IOStmts, 01174 /// since they are the only ones which can have a DoExpr (A(I),I=1,N), 01175 /// and therefore can write to the loop index (I). 01176 /// 01177 /// EqualExpr is the ONLY case where you can tell from the expression alone 01178 /// that a variable is being written to. 01179 01180 void 01181 Statement::_add_out_refs (Expression &expr) 01182 { 01183 if (expr.op() == EQUAL_OP) { 01184 _out_refs.ins (expr.index_id()); 01185 return; 01186 } 01187 else { 01188 for (Iterator<Expression> iter = expr.arg_list(); iter.valid(); ++iter) 01189 _add_out_refs (iter.current()); 01190 } 01191 } 01192 01193 Mutator<Expression> 01194 Statement::iterate_expressions() 01195 { 01196 return Mutator<Expression> (_exprlist); 01197 } 01198 01199 int 01200 Statement::iterate_in_exprs_valid() const 01201 { 01202 return (_exprlist.entries() > 0); 01203 } 01204 01205 Mutator<Expression> 01206 Statement::iterate_in_exprs_guarded() 01207 { 01208 return Mutator<Expression> (_exprlist); 01209 } 01210 01211 int 01212 Statement::iterate_out_exprs_valid() const 01213 { 01214 return 0; 01215 } 01216 01217 Mutator<Expression> 01218 Statement::iterate_out_exprs_guarded() 01219 { 01220 static List<Expression> *_dummy = new List<Expression>; 01221 p_abort( "Statement::iterate_out_exprs_guarded should never be called " 01222 "(should be over-ridden in all usable sub-classes)"); 01223 return Mutator<Expression> (*_dummy); 01224 } 01225 01226 int 01227 Statement::iterate_in_out_exprs_valid() const 01228 { 01229 return 0; 01230 } 01231 01232 Mutator<Expression> 01233 Statement::iterate_in_out_exprs_guarded() 01234 { 01235 static List<Expression> *_dummy = new List<Expression>; 01236 p_abort( "Statement::iterate_in_out_exprs_guarded should never be called " 01237 "(should be over-ridden in all usable sub-classes)"); 01238 return Mutator<Expression> (*_dummy); 01239 } 01240 01241 void 01242 Statement::simplify_expressions() 01243 { 01244 for (Mutator<Expression> iter = iterate_expressions() ; 01245 iter.valid() ; ++iter) { 01246 Assign<Expression> expr_as(iter.assign()); 01247 expr_as = simplify( iter.pull() ); 01248 } 01249 01250 // rebuild the IN/OUT/ACT refs. 01251 01252 build_refs(); 01253 } 01254 01255 01256 01257 void 01258 Statement::relink_lptrs( ProgramUnit &p ) 01259 { 01260 for (Iterator<Assertion> a_iter = _assertion_list; a_iter.valid(); ++a_iter) 01261 if (a_iter.current_valid()) 01262 a_iter.current().relink_aptrs( p ); 01263 01264 for (Iterator<Expression> e_iter = _exprlist; e_iter.valid(); ++e_iter) 01265 if (e_iter.current_valid()) 01266 e_iter.current().relink_eptrs( p ); 01267 01268 SymbolAccessMap * map = new SymbolAccessMap; 01269 01270 if (_access_table) { 01271 for (KeyIterator<Symbol, SymbolAccess> iter = *_access_table; 01272 iter.valid(); 01273 ++iter) { 01274 01275 iter.current_data().relink_eptrs( p ); 01276 SymbolAccess * sa = _access_table->grab(iter.current_key()); 01277 01278 Symbol * sym = p.symtab().find_ref(iter.current_key().name_ref()); 01279 map->ins(*sym, sa); 01280 } 01281 access_table( map ); 01282 } 01283 01284 relink_sptrs(p); 01285 } 01286 01287 void 01288 Statement::relink_sptrs( ProgramUnit & NOTUSED(p) ) 01289 { 01290 /// ... Default to doing nothing 01291 } 01292 01293 /// Helper function: insert leftovers into the overflow 01294 01295 void 01296 Statement::make_overflow(Iterator<BinRep> & iter, const char *exname) 01297 { 01298 warn_overflow_map(exname, iter.current()); 01299 01300 if (!_overflow) { 01301 _overflow = new BinRep; 01302 Set<BinRep> *S = new Set<BinRep>; 01303 _overflow->put_set( S ); 01304 } 01305 01306 _overflow->ins(iter.current()); 01307 } 01308 01309 /// Helper function: Make sure overflow is empty 01310 01311 void 01312 Statement::empty_overflow() 01313 { 01314 if (_overflow) 01315 delete _overflow; 01316 01317 _overflow = 0; 01318 } 01319 01320 /// Helper function: Copies other's base fields into *this. 01321 01322 void 01323 Statement::copy_base(const Statement & other) 01324 { 01325 _exprlist.make_static_list(other._exprlist.entries()); 01326 01327 for (int i=0; i< other._exprlist.entries(); ++i) 01328 if (other._exprlist.valid(i)) 01329 _exprlist.modify(i, other._exprlist[i].clone()); 01330 01331 _type = other._type; 01332 _outer = other._outer; 01333 _state = other._state; 01334 _tag = other._tag; 01335 _line = other._line; 01336 01337 if (other._access_table) { 01338 if (_access_table) { 01339 delete _access_table; 01340 } 01341 _access_table = other._access_table->clone( ); 01342 } else { 01343 _access_table = NULL; 01344 } 01345 01346 /// ... _loop_info = other._loop_info; 01347 01348 if (other._overflow) 01349 _overflow = new BinRep(*(other._overflow)); 01350 else 01351 _overflow = 0; 01352 01353 _successors.clear(); 01354 _predecessors.clear(); 01355 01356 _in_refs.clear(); 01357 _out_refs.clear(); 01358 _act_refs.clear(); 01359 01360 _pre_directives = other._pre_directives; 01361 _post_directives = other._post_directives; 01362 01363 01364 _assertion_list = other._assertion_list; 01365 01366 } 01367 01368 void 01369 Statement::write_access_table( ostream & o) 01370 { 01371 if (_access_table) { 01372 _access_table->write( o, *this ); 01373 } 01374 } 01375 01376 Boolean 01377 Statement::access_table_exists( ) { 01378 01379 if (_access_table) { 01380 return True; 01381 } else { 01382 return False; 01383 } 01384 } 01385 01386 Boolean 01387 Statement::symbol_access_exists( Symbol & sym ) { 01388 01389 if (_access_table) { 01390 SymbolAccess * sa = _access_table->find_ref( sym ); 01391 if (sa) { 01392 return True; 01393 } 01394 } 01395 return False; 01396 } 01397 01398 SymbolAccessMap & 01399 Statement::access_table( ) 01400 { 01401 return (SymbolAccessMap &) *_access_table; 01402 } 01403 01404 void 01405 Statement::incorporate_access_table( const SymbolAccessMap & sam ) 01406 { 01407 this->_access_table->incorporate( sam ); 01408 } 01409 01410 void 01411 Statement::ins_access( SymbolAccessMap & map ) 01412 { 01413 for (KeyIterator<Symbol, SymbolAccess> iter = map; 01414 iter.valid(); 01415 ++iter) { 01416 01417 Symbol & sym = iter.current_key(); 01418 SymbolAccess & sym_acc = iter.current_data(); 01419 01420 for (Mutator<AbstractAccess> muter_r = sym_acc.muter_read(); 01421 muter_r.valid(); 01422 ++muter_r) { 01423 ins_read_access(sym, muter_r.grab()); 01424 } 01425 for (Mutator<AbstractAccess> muter_w = sym_acc.muter_write(); 01426 muter_w.valid(); 01427 ++muter_w) { 01428 ins_write_access(sym, muter_w.grab()); 01429 } 01430 for (Mutator<AbstractAccess> muter_rw = sym_acc.muter_readwrite(); 01431 muter_rw.valid(); 01432 ++muter_rw) { 01433 ins_readwrite_access(sym, muter_rw.grab()); 01434 } 01435 } 01436 } 01437 01438 void 01439 Statement::ins_read_access( Symbol & sym, List<AbstractAccess> & list ) 01440 { 01441 for (Mutator<AbstractAccess> muter_r = list; 01442 muter_r.valid(); 01443 ++muter_r) { 01444 ins_read_access( sym, muter_r.grab()); 01445 } 01446 } 01447 01448 void 01449 Statement::ins_readwrite_access( Symbol & sym, List<AbstractAccess> & list ) 01450 { 01451 for (Mutator<AbstractAccess> muter_r = list; 01452 muter_r.valid(); 01453 ++muter_r) { 01454 ins_readwrite_access( sym, muter_r.grab()); 01455 } 01456 } 01457 01458 void 01459 Statement::ins_write_access( Symbol & sym, List<AbstractAccess> & list ) 01460 { 01461 for (Mutator<AbstractAccess> muter_r = list; 01462 muter_r.valid(); 01463 ++muter_r) { 01464 ins_write_access( sym, muter_r.grab()); 01465 } 01466 } 01467 01468 void 01469 Statement::ins_read_access( Symbol & sym, AbstractAccess * aa ) 01470 { 01471 SymbolAccess * sa = _access_table->find_ref( sym ); 01472 if (sa) { 01473 sa->add_read( aa ); 01474 } else { 01475 /// ... Didn't have a SymbolAccess for this symbol before 01476 SymbolAccess *new_sa = new SymbolAccess; 01477 new_sa->add_read( aa ); 01478 _access_table->ins( sym, new_sa ); 01479 } 01480 } 01481 01482 void 01483 Statement::ins_write_access( Symbol & sym, AbstractAccess * aa ) 01484 { 01485 SymbolAccess * sa = _access_table->find_ref( sym ); 01486 if (sa) { 01487 sa->add_write( aa ); 01488 } else { 01489 /// ... Didn't have a SymbolAccess for this symbol before 01490 SymbolAccess *new_sa = new SymbolAccess; 01491 new_sa->add_write( aa ); 01492 _access_table->ins( sym, new_sa ); 01493 } 01494 } 01495 01496 void 01497 Statement::ins_readwrite_access( Symbol & sym, AbstractAccess * aa ) 01498 { 01499 SymbolAccess * sa = _access_table->find_ref( sym ); 01500 if (sa) { 01501 sa->add_readwrite( aa ); 01502 } else { 01503 /// ... Didn't have a SymbolAccess for this symbol before 01504 SymbolAccess *new_sa = new SymbolAccess; 01505 new_sa->add_readwrite( aa ); 01506 _access_table->ins( sym, new_sa ); 01507 } 01508 } 01509 01510 KeyIterator<Symbol, SymbolAccess> 01511 Statement::iter_access_table_guarded( ) { 01512 01513 p_assert(_access_table, 01514 "No access table for this statement - use access_table_exists first"); 01515 01516 KeyIterator<Symbol, SymbolAccess> iter = *_access_table; 01517 return iter; 01518 } 01519 01520 /// Before calling one of these routines, call symbol_access_exists 01521 /// to be sure an access table exists and there is data for the 01522 /// symbol in it. 01523 01524 Iterator<AbstractAccess> 01525 Statement::iter_read_guarded( Symbol & sym ) { 01526 01527 p_assert(_access_table, 01528 "No access table for this statement - use symbol_access_exists first"); 01529 01530 SymbolAccess * sa = _access_table->find_ref( sym ); 01531 01532 p_assert(sa, 01533 "No symbol access for this statement - use symbol_access_exists first"); 01534 01535 Iterator<AbstractAccess> iter = sa->iter_read(); 01536 return iter; 01537 } 01538 01539 Iterator<AbstractAccess> 01540 Statement::iter_write_guarded( Symbol & sym ) { 01541 01542 p_assert(_access_table, 01543 "No access table for this statement - use symbol_access_exists first"); 01544 01545 SymbolAccess * sa = _access_table->find_ref( sym ); 01546 01547 p_assert(sa, 01548 "No symbol access for this statement - use symbol_access_exists first"); 01549 01550 Iterator<AbstractAccess> iter = sa->iter_write(); 01551 return iter; 01552 } 01553 01554 Iterator<AbstractAccess> 01555 Statement::iter_readwrite_guarded( Symbol & sym ) { 01556 01557 p_assert(_access_table, 01558 "No access table for this statement - use symbol_access_exists first"); 01559 01560 SymbolAccess * sa = _access_table->find_ref( sym ); 01561 01562 p_assert(sa, 01563 "No symbol access for this statement - use symbol_access_exists first"); 01564 01565 Iterator<AbstractAccess> iter = sa->iter_readwrite(); 01566 return iter; 01567 } 01568 01569 /// Converts an objects stmt-pointer fields from dummy\'s to actual pointers 01570 01571 void 01572 Statement::_setptrs(Dictionary<VoidPtrDef> &tags, 01573 const FormatDB & NOTUSED(formats)) 01574 { 01575 Iterator<Statement> iter = _successors; 01576 01577 /// ... set successors 01578 for (; iter.valid(); ++iter) 01579 _successors._modify( 01580 _successors._member(iter.current()), 01581 *((Statement *)tags[ iter.current().tag() ].ptr_ref())); 01582 01583 /// ... THIS IS VERY BAD FORM! The _member function should NOT be used 01584 /// ... outside of the RefSet<T> implementation. 01585 01586 /// ... set predecessors 01587 for (iter = _predecessors; iter.valid(); ++iter) 01588 _predecessors._modify( 01589 _predecessors._member(iter.current()), 01590 *((Statement *)tags[ iter.current().tag() ].ptr_ref())); 01591 01592 /// ... THIS IS VERY BAD FORM! The _member function should NOT be used 01593 /// ... outside of the RefSet<T> implementation. 01594 01595 /// ... Set outer field 01596 if (_outer) { 01597 makeptr_ptr(&_outer, tags); 01598 } 01599 } 01600 01601 /// Convert the common fields of a statement return true if a match 01602 /// is found 01603 01604 int 01605 Statement::check_common_fields(String & field, 01606 BinRep & second, 01607 ExprTable & etable, 01608 Dictionary<NextEntry> *next_table, 01609 char *caller) 01610 { 01611 if (field == "successors") { 01612 convert_stmt_list(second, _successors, _successors_list, caller); 01613 return 1; 01614 } 01615 else if (field == "predecessors") { 01616 convert_stmt_list(second, _predecessors, _predecessors_list, caller); 01617 return 1; 01618 } 01619 else if (field == "in_refs") { 01620 /// Discard (rebuild later) 01621 /// convert_expr_list(second, _in_refs, _in_refs_list, etable, caller); 01622 return 1; 01623 } 01624 else if (field == "out_refs") { 01625 /// Discard (rebuild later) 01626 /// convert_expr_list(second, _out_refs, _out_refs_list, etable, caller); 01627 return 1; 01628 } 01629 else if (field == "act_refs") { 01630 /// Discard (rebuild later) 01631 /// convert_expr_list(second, _act_refs, _act_refs_list, etable, caller); 01632 return 1; 01633 } 01634 else if (field == "outer") { 01635 _outer = temp_stmt_ptr(second); 01636 return 1; 01637 } 01638 else if (field == "assertions") { 01639 if (second.is_tuple()) { 01640 List<BinRep> & S = second.to_tuple(); 01641 if (S.entries() > 0) { 01642 if (S[0].is_string()) 01643 convert_string_list(second, _pre_directives, caller); 01644 else { 01645 convert_assert_list(second, _assertion_list, 01646 etable, caller); 01647 } 01648 } 01649 } 01650 return 1; 01651 } 01652 else if (field == "directives") { 01653 if (second.is_tuple()) { 01654 List<BinRep> & S = second.to_tuple(); 01655 if (S.entries() > 0) { 01656 if (S[0].is_string()) 01657 convert_string_list(second, _pre_directives, caller); 01658 else { 01659 convert_assert_list(second, _assertion_list, 01660 etable, caller); 01661 } 01662 } 01663 } 01664 return 1; 01665 } 01666 else if (field == "next") 01667 if (! second.is_string()) { 01668 cerr << "Statement::convert: 'next' field in " << _tag 01669 << " is not a string\n"; 01670 p_abort( "(see above message)" ); 01671 } 01672 else { 01673 NextEntry *next = new NextEntry(_tag, second); 01674 01675 next_table->ins(next); 01676 return 1; 01677 } 01678 else if (field == "line") { 01679 p_assert(second.is_integer(), "line number is not an integer"); 01680 _line = second.to_integer(); 01681 return 1; 01682 } 01683 01684 return 0; 01685 } 01686 01687 /// Print all base fields followed by a close brace (in debugging 01688 /// mode, printing a statement prints an open backet) 01689 01690 void 01691 Statement::print_fields(ostream & o) const 01692 { 01693 01694 if (_successors.entries() > 0) { 01695 o << "succ = "; 01696 print_stmt_tags(o, (RefSet<Statement> &) _successors); 01697 o << ", "; 01698 } 01699 if (_predecessors.entries() > 0) { 01700 o << "pred = "; 01701 print_stmt_tags(o, (RefSet<Statement> &) _predecessors); 01702 o << ", "; 01703 } 01704 if (_in_refs.entries() > 0) { 01705 o << "in_refs = "; 01706 print_expr_list(o, (RefSet<Expression> &) _in_refs); 01707 o << ", "; 01708 } 01709 if (_out_refs.entries() > 0) { 01710 o << "out_refs = "; 01711 print_expr_list(o, (RefSet<Expression> &) _out_refs); 01712 o << ", "; 01713 } 01714 if (_act_refs.entries() > 0) { 01715 o << "act_refs = "; 01716 print_expr_list(o, (RefSet<Expression> &) _act_refs); 01717 o << ", "; 01718 } 01719 if (_outer) 01720 o << "outer = " << _outer->tag() << ", "; 01721 if (_pre_directives.entries() > 0) { 01722 o << "pre-dir = "; 01723 print_string_list(o, (List<StringElem> &) _pre_directives); 01724 o << ", "; 01725 } 01726 if (_post_directives.entries()>0) { 01727 o << "post-dir = "; 01728 print_string_list(o, (List<StringElem> &) _post_directives); 01729 o << ", "; 01730 } 01731 if (_line != -1) 01732 o << "line = " << _line << ", "; 01733 if (_work_stack.entries() > 0) { 01734 o << "work-stack = " << _work_stack << ", "; 01735 } 01736 01737 if (assertions().entries() > 0) 01738 o << "assertions = " << assertions(); 01739 01740 if (_overflow) 01741 o << "overflow = " << *_overflow; 01742 01743 if (_access_table) { 01744 o << "access table = " << *_access_table; 01745 } 01746 01747 if ((_type == ENTRY_STMT) && 01748 (((EntryStmt *) this)->access_summary_exists())) { 01749 o << "access summary = " << ((EntryStmt *)this)->access_summary(); 01750 } 01751 01752 /// ... comment '{' 01753 01754 o << " }"; 01755 } 01756 01757 01758 /// This outputs the statement with all debugging info (ie-all fields!) 01759 01760 ostream & 01761 operator << (ostream & o, const Statement & st) 01762 { 01763 ostrstream o_src, o_dbg; 01764 01765 st.print_debug(o_src, 0); 01766 st.print_debug(o_dbg, 1); 01767 01768 st.print_fields(o_dbg); 01769 01770 o_src << '\0'; 01771 o_dbg << '\0'; 01772 01773 char *src_line = o_src.str(); 01774 char *dbg_line = o_dbg.str(); 01775 int poss_value = -1; 01776 01777 if (st._type == LABEL_STMT) 01778 poss_value = st.value(); 01779 01780 split_line(o, 6, st._tag, poss_value, src_line); 01781 split_line(o, 9, "", -1, dbg_line); 01782 01783 /// ... delete src_line; 01784 /// ... delete dbg_line; 01785 /// ... silvius: fixed above 01786 o_src.freeze(0); 01787 o_dbg.freeze(0); 01788 01789 return o; 01790 } 01791 01792 inline void 01793 print_expr_ptr(ostream & o, const Expression * e) 01794 { 01795 if (e) 01796 o << *e; 01797 else 01798 o << "<UNDEF>"; 01799 } 01800 01801 static char *type_string[] = { 01802 "UNDEFINED_STMT", 01803 "DO_STMT", "ENDDO_STMT", "WHILE_STMT", 01804 "ASSIGNMENT_STMT", 01805 "IF_STMT", "ELSEIF_STMT", "IMPLIED_GOTO_STMT", "ENDIF_STMT", "ELSE_STMT", 01806 "ASSIGN_STMT", 01807 "READ_STMT", "WRITE_STMT", 01808 "PRINT_STMT", "OPEN_STMT", "CLOSE_STMT", "REWIND_STMT", 01809 "BACKSPACE_STMT", "ENDFILE_STMT", "INQUIRE_STMT", 01810 "STOP_STMT", "PAUSE_STMT", 01811 "FLOW_ENTRY_STMT", "FLOW_EXIT_STMT", 01812 "BLOCK_ENTRY_STMT", "BLOCK_EXIT_STMT", 01813 "ENTRY_STMT", "CALL_STMT", "RETURN_STMT", 01814 "LABEL_STMT", "GOTO_STMT", "ARITHMETIC_IF_STMT", 01815 "COMPUTED_GOTO_STMT", "ASSIGNED_GOTO_STMT", 01816 "ALLOCATE_STMT", "DEALLOCATE_STMT", "NULLIFY_STMT", 01817 "DIRECTIVE_STMT", "STMT_PTR"}; 01818 01819 void 01820 Statement::error(char *method_name) const 01821 { 01822 cerr << "A(n) '" << type_string[(int) _type] 01823 << "' object attempted to call the undefined method '" 01824 << method_name << "'.\n"; 01825 01826 p_abort("(see above mesage)"); 01827 } 01828 01829 01830 01831 /// Statement constructor takes two arguments: 01832 /// The statement type and the statement tag 01833 01834 Statement::Statement(const char *l, STMT_TYPE st) 01835 : _type(st), _tag(l) 01836 { 01837 #ifdef CLASS_INSTANCE_REGISTRY 01838 register_instance(STATEMENT, sizeof(Statement), this); 01839 #endif 01840 01841 _outer = 0; 01842 _overflow = 0; 01843 01844 _access_table = NULL; 01845 01846 #ifdef PERFORMANCE_EVAL 01847 _perf_estimator = NULL; 01848 _stmtProfile = 0L; 01849 #endif 01850 01851 _line = -1; 01852 } 01853 01854 Statement::~Statement() 01855 { 01856 #ifdef CLASS_INSTANCE_REGISTRY 01857 unregister_instance(STATEMENT, this); 01858 #endif 01859 01860 if (_access_table) { 01861 delete _access_table; 01862 } 01863 01864 if (_overflow) 01865 delete _overflow; 01866 _overflow = 0; 01867 } 01868 01869 /// Check in/out/act _refs sets by saving them and 01870 /// recomputing them, then checking the saved one against 01871 /// the new one. 01872 01873 int 01874 Statement::in_out_refs_structures_OK() const 01875 { 01876 const RefSet<Expression> act_refs_old = _act_refs; 01877 const RefSet<Expression> in_refs_old = _in_refs; 01878 const RefSet<Expression> out_refs_old = _out_refs; 01879 01880 (CASTAWAY(Statement *) this)->build_refs(); 01881 01882 /// ... Check _act_refs: 01883 01884 int OK = 1; 01885 if ( !(_act_refs == act_refs_old) ) { 01886 cerr << "For statement: " << endl; 01887 cerr << *this << endl; 01888 cerr << "_act_refs set was: " << endl; 01889 cerr << " " << act_refs_old << endl; 01890 cerr << "Should have been: " << endl; 01891 cerr << " " << _act_refs << endl; 01892 OK = 0; 01893 } 01894 01895 /// ... Check _in_refs: 01896 01897 if ( !(_in_refs == in_refs_old) ) { 01898 if (OK) { 01899 cerr << "For statement: " << endl; 01900 cerr << *this << endl; 01901 } 01902 cerr << "_in_refs set was: " << endl; 01903 cerr << " " << in_refs_old << endl; 01904 cerr << "Should have been: " << endl; 01905 cerr << " " << _in_refs << endl; 01906 OK = 0; 01907 } 01908 01909 /// ... Check _out_refs: 01910 01911 if ( !(_out_refs == out_refs_old) ) { 01912 if (OK) { 01913 cerr << "For statement: " << endl; 01914 cerr << *this << endl; 01915 } 01916 cerr << "_out_refs set was: " << endl; 01917 cerr << " " << out_refs_old << endl; 01918 cerr << "Should have been: " << endl; 01919 cerr << " " << _out_refs << endl; 01920 OK = 0; 01921 } 01922 01923 return OK; 01924 } 01925 01926 Listable * 01927 Statement::listable_clone() const 01928 { 01929 Statement *new_stmt = clone(); 01930 01931 if (dbx_statement_cloning_debug_level >= 100) { 01932 cout << "**Cloned statement:\n" << flush << *this 01933 << "** into new statement:\n" << flush << *new_stmt; 01934 } 01935 01936 return new_stmt; 01937 } 01938 01939 int 01940 Statement::io_list_valid() const 01941 { 01942 return 0; 01943 } 01944 01945 const Expression & 01946 Statement::lhs() const 01947 { 01948 error("lhs()"); 01949 return DUMMY_EXPR; 01950 } 01951 01952 Expression & 01953 Statement::lhs() 01954 { 01955 error("lhs()"); 01956 return DUMMY_EXPR; 01957 } 01958 01959 const Expression & 01960 Statement::rhs() const 01961 { 01962 error("rhs()"); 01963 return DUMMY_EXPR; 01964 } 01965 01966 Expression & 01967 Statement::rhs() 01968 { 01969 error("rhs()"); 01970 return DUMMY_EXPR; 01971 } 01972 01973 Statement * 01974 Statement::follow_ref() const 01975 { 01976 return NULL; 01977 } 01978 01979 Statement * 01980 Statement::lead_ref() const 01981 { 01982 return NULL; 01983 } 01984 01985 Statement * 01986 Statement::matching_if_ref() const 01987 { 01988 return NULL; 01989 } 01990 01991 Statement * 01992 Statement::matching_endif_ref() const 01993 { 01994 return NULL; 01995 } 01996 01997 const Expression & 01998 Statement::index() const 01999 { 02000 error("index()"); 02001 return DUMMY_EXPR; 02002 } 02003 02004 Expression & 02005 Statement::index() 02006 { 02007 error("index()"); 02008 return DUMMY_EXPR; 02009 } 02010 02011 const Expression & 02012 Statement::init() const 02013 { 02014 error("init()"); 02015 return DUMMY_EXPR; 02016 } 02017 02018 Expression & 02019 Statement::init() 02020 { 02021 error("init()"); 02022 return DUMMY_EXPR; 02023 } 02024 02025 const Expression & 02026 Statement::limit() const 02027 { 02028 error("limit()"); 02029 return DUMMY_EXPR; 02030 } 02031 02032 Expression & 02033 Statement::limit() 02034 { 02035 error("limit()"); 02036 return DUMMY_EXPR; 02037 } 02038 02039 const Expression & 02040 Statement::step() const 02041 { 02042 error("step()"); 02043 return DUMMY_EXPR; 02044 } 02045 02046 Expression & 02047 Statement::step() 02048 { 02049 error("step()"); 02050 return DUMMY_EXPR; 02051 } 02052 02053 const Expression & 02054 Statement::expr() const 02055 { 02056 error("expr()"); 02057 return DUMMY_EXPR; 02058 } 02059 02060 Expression & 02061 Statement::expr() 02062 { 02063 error("expr()"); 02064 return DUMMY_EXPR; 02065 } 02066 02067 const Expression & 02068 Statement::expr_guarded() const 02069 { 02070 error("expr_guarded()"); 02071 return DUMMY_EXPR; 02072 } 02073 02074 Expression & 02075 Statement::expr_guarded() 02076 { 02077 error("expr_guarded()"); 02078 return DUMMY_EXPR; 02079 } 02080 02081 int 02082 Statement::expr_valid() const 02083 { 02084 return 0; 02085 } 02086 02087 const Statement * 02088 Statement::target_ref() const 02089 { 02090 return NULL; 02091 } 02092 02093 Statement * 02094 Statement::target_ref() 02095 { 02096 return NULL; 02097 } 02098 02099 ASSIGN_TYPE 02100 Statement::atype() const 02101 { 02102 return INVALID_ASSIGN; 02103 } 02104 02105 const Format * 02106 Statement::format_ref() const 02107 { 02108 return NULL; 02109 } 02110 02111 Format * 02112 Statement::format_ref() 02113 { 02114 return NULL; 02115 } 02116 02117 const RefList<Statement> & 02118 Statement::label_list() const 02119 { 02120 error("label_list()"); 02121 return *((RefList<Statement> *) 0); 02122 } 02123 02124 RefList<Statement> & 02125 Statement::label_list() 02126 { 02127 error("label_list()"); 02128 return *((RefList<Statement> *) 0); 02129 } 02130 02131 const List<s_control_type> & 02132 Statement::s_control_guarded() const 02133 { 02134 error("s_control_guarded()"); 02135 return *((List<s_control_type> *) 0); 02136 } 02137 02138 List<s_control_type> & 02139 Statement::s_control_guarded() 02140 { 02141 error("s_control_guarded()"); 02142 return *((List<s_control_type> *) 0); 02143 } 02144 02145 int 02146 Statement::s_control_valid() const 02147 { 02148 return False; 02149 } 02150 02151 const Expression & 02152 Statement::io_list_guarded() const 02153 { 02154 error("io_list_guarded()"); 02155 return DUMMY_EXPR; 02156 } 02157 02158 Expression & 02159 Statement::io_list_guarded() 02160 { 02161 error("io_list_guarded()"); 02162 return DUMMY_EXPR; 02163 } 02164 02165 const Expression & 02166 Statement::routine_guarded() const 02167 { 02168 error("routine_guarded()"); 02169 return DUMMY_EXPR; 02170 } 02171 02172 Expression & 02173 Statement::routine_guarded() 02174 { 02175 error("routine_guarded()"); 02176 return DUMMY_EXPR; 02177 } 02178 02179 int 02180 Statement::routine_valid() const 02181 { 02182 return 0; 02183 } 02184 02185 const Expression & 02186 Statement::parameters_guarded() const 02187 { 02188 error("parameters_guarded()"); 02189 return DUMMY_EXPR; 02190 } 02191 02192 Expression & 02193 Statement::parameters_guarded() 02194 { 02195 error("parameters_guarded()"); 02196 return DUMMY_EXPR; 02197 } 02198 02199 int 02200 Statement::parameters_valid() const 02201 { 02202 return 0; 02203 } 02204 02205 int 02206 Statement::value() const 02207 { 02208 error("value()"); 02209 return -1; 02210 } 02211 02212 /// will be redefined by sub-classes if field exists 02213 02214 void 02215 Statement::lhs(Expression * NOTUSED(e)) 02216 { 02217 error("lhs(Expression)"); 02218 } 02219 02220 void 02221 Statement::rhs(Expression * NOTUSED(e)) 02222 { 02223 error("rhs(Expression)"); 02224 } 02225 02226 void 02227 Statement::index(Expression * NOTUSED(e)) 02228 { 02229 error("index(Expression)"); 02230 } 02231 02232 void 02233 Statement::init(Expression * NOTUSED(e)) 02234 { 02235 error("init(Expression)"); 02236 } 02237 02238 void 02239 Statement::limit(Expression * NOTUSED(e)) 02240 { 02241 error("limit(Expression)"); 02242 } 02243 02244 void 02245 Statement::step(Expression * NOTUSED(e)) 02246 { 02247 error("step(Expression)"); 02248 } 02249 02250 void 02251 Statement::expr(Expression * NOTUSED(e)) 02252 { 02253 error("expr(Expression)"); 02254 } 02255 02256 void 02257 Statement::target(Statement * NOTUSED(s)) 02258 { 02259 error("target(Expression)"); 02260 } 02261 02262 void 02263 Statement::io_list(Expression * NOTUSED(e)) 02264 { 02265 error("io_list(Expression)"); 02266 } 02267 02268 void 02269 Statement::routine(Expression * NOTUSED(e)) 02270 { 02271 error("routine(Expression)"); 02272 } 02273 02274 void 02275 Statement::parameters(Expression * NOTUSED(e)) 02276 { 02277 error("parameters(Expression)"); 02278 } 02279 02280 void 02281 Statement::value(int NOTUSED(i)) 02282 { 02283 error("value(Expression)"); 02284 } 02285 02286 String 02287 Statement::get_loop_name() 02288 { 02289 error("get_loop_name()"); 02290 return "ERROR"; 02291 } 02292 02293 /// This one is to satisfy Listable 02294 02295 void 02296 Statement::print(ostream & o) const 02297 { 02298 o << *this; 02299 } 02300 02301 void 02302 Statement::write(ostream & o, int &indent, char *type GIV("")) const 02303 { 02304 ostrstream o_src; 02305 02306 fortran_write(o_src, indent, type); 02307 02308 o_src << '\0'; 02309 02310 char *src_line = o_src.str(); 02311 int poss_value = -1; 02312 02313 if (_type == LABEL_STMT) 02314 poss_value = value(); 02315 02316 split_line(o, 0, "", poss_value, src_line); 02317 02318 /// ... delete src_line; 02319 /// ... silvius: fixed above 02320 o_src.freeze(0); 02321 02322 /// ... Take care of printing the loop private variables 02323 /// ... for parallel DO loops for Cedar Fortran 02324 02325 if ((this->stmt_class() == DO_STMT) && 02326 (switch_value( "output_lang" ) == DT_CEDAR_FORTRAN) && 02327 this->marked_parallel() ) { 02328 02329 Symtab privatesyms; 02330 02331 RefSet<Symbol> *privates = this->private_vars_ref(); 02332 for (Iterator<Symbol> piter = *privates; 02333 piter.valid(); 02334 ++piter) { 02335 privatesyms.ins(piter.current().clone()); 02336 } 02337 delete privates; 02338 privatesyms.write(o, indent); /// ... Print the private symbol table 02339 } 02340 } 02341 02342 RefSet<Statement> * 02343 Statement::build_succ(const StmtList & NOTUSED(stmts)) const 02344 { 02345 RefSet<Statement> *new_succ = new RefSet<Statement>; 02346 02347 new_succ->ins(*next_ref()); 02348 02349 return new_succ; 02350 } 02351 02352 void 02353 Statement::build_refs() 02354 { 02355 _in_refs.clear(); 02356 _out_refs.clear(); 02357 _act_refs.clear(); 02358 } 02359 02360 02361 /// Assume that the flowgraph for statement <s> has changed. Update the 02362 /// pred() and succ() fields of all affected statements. 02363 02364 02365 void 02366 Statement::fix_flow( StmtList & stmts ) 02367 { 02368 RefSet<Statement> &old_succ = _successors; 02369 RefSet<Statement> *new_succ = build_succ(stmts); 02370 02371 for (Iterator<Statement> iter_a = old_succ; iter_a.valid(); ++iter_a) { 02372 if (! new_succ->member( iter_a.current() )) 02373 iter_a.current()._predecessors.del( *this ); 02374 } 02375 02376 for (Iterator<Statement> iter_b = *new_succ; iter_b.valid(); ++iter_b) { 02377 if (! old_succ.member( iter_b.current() )) 02378 iter_b.current()._predecessors.ins( *this ); 02379 } 02380 02381 _successors = (*new_succ); 02382 02383 delete new_succ; 02384 } 02385 02386 02387 /// To delete a statement <s>: (StmtList::del(Statement) does all this!) 02388 /// (1) create a list <l> of all predecessors of the statement <s>. 02389 /// (2) delete the entry <s> from the pred() lists of all successors of <s>. 02390 /// (3) delete the statement [ links are now inconsistant ]. 02391 /// (4) call fix_flow( statements in <l> ). 02392 02393 02394 void 02395 Statement::del_flow( StmtList & NOTUSED(stmts)) 02396 { 02397 for (Iterator<Statement> iter_a = succ(); iter_a.valid(); ++iter_a) 02398 iter_a.current()._predecessors.del( *this ); 02399 02400 for (Iterator<Statement> iter_b = pred(); iter_b.valid(); ++iter_b) 02401 iter_b.current()._successors.del( *this ); 02402 02403 _successors.clear(); 02404 _predecessors.clear(); 02405 } 02406 02407 02408 02409 02410 void 02411 AssignmentStmt::build_refs() 02412 { 02413 /// ... _in_refs and _act_refs come from the right-hand side and 02414 /// ... any array subscripting on the left-hand side 02415 02416 _in_refs.clear(); 02417 _add_in_refs(this->rhs()); 02418 02419 if (this->lhs().op() == ARRAY_REF_OP) 02420 _add_in_refs(this->lhs().subscript()); 02421 else if (this->lhs().op() == SUBSTRING_OP) 02422 _add_in_refs(this->lhs().bound()); 02423 02424 _act_refs.clear(); 02425 _add_act_refs(this->rhs()); 02426 02427 if (this->lhs().op() == ARRAY_REF_OP) 02428 _add_act_refs(this->lhs().subscript()); 02429 if (this->lhs().op() == SUBSTRING_OP) 02430 _add_act_refs(this->lhs().bound()); 02431 02432 /// ... _out_refs are the act_refs plus the left-hand side expression 02433 02434 _out_refs = _act_refs; 02435 _out_refs.ins(this->lhs()); 02436 } 02437 02438 int 02439 AssignmentStmt::iterate_in_exprs_valid() const 02440 { 02441 return (_exprlist.valid(RHS) == True && 02442 _exprlist[RHS].op() != OMEGA_OP); 02443 } 02444 02445 Mutator<Expression> 02446 AssignmentStmt::iterate_in_exprs_guarded() 02447 { 02448 /// input expr is rhs 02449 return Mutator<Expression>(_exprlist,&_exprlist[RHS],&_exprlist[RHS]); 02450 } 02451 02452 int 02453 AssignmentStmt::iterate_out_exprs_valid() const 02454 { 02455 return (_exprlist.valid(LHS) == True && 02456 _exprlist[LHS].op() != OMEGA_OP); 02457 } 02458 02459 Mutator<Expression> 02460 AssignmentStmt::iterate_out_exprs_guarded() 02461 { 02462 /// output expr is lhs 02463 return Mutator<Expression>(_exprlist,&_exprlist[LHS],&_exprlist[LHS]); 02464 } 02465 02466 void 02467 AssignmentStmt::lhs(Expression *e) 02468 { 02469 _exprlist.modify(LHS, e); 02470 build_refs(); 02471 } 02472 02473 void 02474 AssignmentStmt::rhs(Expression *e) 02475 { 02476 _exprlist.modify(RHS, e); 02477 build_refs(); 02478 } 02479 02480 AssignmentStmt::AssignmentStmt(const char *l) 02481 : Statement(l, ASSIGNMENT_STMT) 02482 { 02483 _exprlist.make_static_list(2); 02484 _exprlist.modify(LHS, omega()); 02485 _exprlist.modify(RHS, omega()); 02486 } 02487 02488 AssignmentStmt::AssignmentStmt(const char *l, Expression *lhs_exp, 02489 Expression *rhs_exp) 02490 : Statement(l, ASSIGNMENT_STMT) 02491 { 02492 if (!shape_conformance(*lhs_exp, *rhs_exp)) { 02493 cerr << "Assignment statement not in shape conformance!" << endl 02494 << "LHS: " << *lhs_exp << " (" << lhs_exp->type() << ")\n"; 02495 cerr << "RHS: " << *rhs_exp << " (" << rhs_exp->type() << ")\n"; 02496 p_assert(0, "AssignmentStatement::AssignmentStmt(char*, Expr, Expr):" 02497 "Exprs not in shape conformance"); 02498 } 02499 _exprlist.make_static_list(2); 02500 _exprlist.modify(LHS, null_to_omega(lhs_exp)); 02501 _exprlist.modify(RHS, null_to_omega(rhs_exp)); 02502 build_refs(); 02503 } 02504 02505 AssignmentStmt::AssignmentStmt(const AssignmentStmt & stmt) 02506 : Statement(stmt.tag(), ASSIGNMENT_STMT) 02507 { 02508 copy_base(stmt); 02509 02510 _exprlist.modify(LHS, stmt._exprlist[LHS].clone() ); 02511 _exprlist.modify(RHS, stmt._exprlist[RHS].clone() ); 02512 02513 build_refs(); 02514 } 02515 02516 AssignmentStmt & 02517 AssignmentStmt:: operator = (const AssignmentStmt & stmt) 02518 { 02519 copy_base(stmt); 02520 02521 _exprlist.modify(LHS, stmt._exprlist[LHS].clone() ); 02522 _exprlist.modify(RHS, stmt._exprlist[RHS].clone() ); 02523 02524 build_refs(); 02525 return *this; 02526 } 02527 02528 Statement * 02529 AssignmentStmt::clone() const 02530 { 02531 return new AssignmentStmt(*this); 02532 } 02533 02534 AssignmentStmt::~AssignmentStmt() 02535 { 02536 /// ... nothing to do 02537 } 02538 02539 02540 void 02541 AssignmentStmt::fortran_write(ostream &o, int &indent, 02542 char *NOTUSED(type)) const 02543 { 02544 fortran_indent( o, indent ); 02545 02546 print_expr_ptr(o, &_exprlist[LHS]); 02547 o << " = "; 02548 print_expr_ptr(o, &_exprlist[RHS]); 02549 } 02550 02551 void 02552 AssignmentStmt::print_debug(ostream & o, int debug) const 02553 { 02554 if (!debug) { 02555 print_expr_ptr(o, &_exprlist[LHS]); 02556 o << " = "; 02557 print_expr_ptr(o, &_exprlist[RHS]); 02558 } 02559 else 02560 o << " {"; /// ... comment '}' 02561 } 02562 02563 int 02564 AssignmentStmt::structures_OK() const 02565 { 02566 int OK = Statement::in_out_refs_structures_OK(); 02567 02568 return OK; 02569 } 02570 02571 void 02572 AssignmentStmt::exchange_convert( VDL &vdl ) 02573 { 02574 Statement::exchange_convert( vdl ); 02575 02576 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 02577 02578 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 02579 02580 BinRep *br = new BinRep( new List<BinRep> ); 02581 br->to_tuple().ins_last( new BinRep( "st" )); 02582 br->to_tuple().ins_last( new BinRep( "ASSIGNMENT" )); 02583 S.ins( br ); 02584 02585 br = new BinRep( new List<BinRep> ); 02586 br->to_tuple().ins_last( new BinRep( "lhs" )); 02587 br->to_tuple().ins_last( new BinRep( this->lhs().exchange_expr(vdl) )); 02588 S.ins( br ); 02589 02590 br = new BinRep( new List<BinRep> ); 02591 br->to_tuple().ins_last( new BinRep( "rhs" )); 02592 br->to_tuple().ins_last( new BinRep( this->rhs().exchange_expr(vdl) )); 02593 S.ins( br ); 02594 } 02595 02596 void 02597 AssignmentStmt::convert(BinRep & stmt, ExprTable & etable, 02598 Symtab & NOTUSED(symtab), 02599 const NamelistDict & NOTUSED(namelists), 02600 const FormatDB & NOTUSED(formats), 02601 Dictionary<NextEntry> *next_table) 02602 { 02603 empty_overflow(); 02604 02605 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 02606 List<BinRep> & t = iter.current().to_tuple(); 02607 BinRep & second = t[1]; /// ... The second argument of tuple pairs 02608 String field; 02609 02610 t[0].to_string( field ); 02611 02612 if (!check_common_fields(field, second, etable, 02613 next_table, "AssignmentStmt")) 02614 if (field == "lhs") 02615 _exprlist.modify(LHS, convert_expr(second, etable, 02616 "AssignmentStmt")); 02617 else if (field == "rhs") 02618 _exprlist.modify(RHS, convert_expr(second, etable, 02619 "AssignmentStmt")); 02620 else if ((field != "prev") && (field != "st")) 02621 make_overflow(iter, "AssignmentStmt"); 02622 } 02623 02624 if (!shape_conformance(lhs(), rhs())) { 02625 cerr << "Assignment statement not in shape conformance!" << endl 02626 << "LHS: " << lhs() << " (" << lhs().type() << ")\n"; 02627 cerr << "RHS: " << rhs() << " (" << rhs().type() << ")\n"; 02628 p_assert(0, "AssignmentStatement::convert( ):" 02629 "Expressions not in shape conformance"); 02630 } 02631 02632 } 02633 02634 02635 02636 void 02637 DoStmt::build_refs() 02638 { 02639 /// ... _in_refs and _act_refs come from the _init, _limit, and _step exprs 02640 02641 _in_refs.clear(); 02642 _add_in_refs(this->init()); 02643 _add_in_refs(this->limit()); 02644 _add_in_refs(this->step()); 02645 02646 _act_refs.clear(); 02647 _add_act_refs(this->init()); 02648 _add_act_refs(this->limit()); 02649 _add_act_refs(this->step()); 02650 02651 /// ... _out_refs are the act_refs plus the index expression 02652 02653 _out_refs = _act_refs; 02654 _out_refs.ins(this->index()); 02655 02656 } 02657 02658 void 02659 DoStmt::index(Expression *e) 02660 { 02661 p_assert(e->op() == ID_OP, "DoStmt::index(Expression *): IDExpr expected"); 02662 02663 _exprlist.modify(DO_INDEX, e); 02664 build_refs(); 02665 } 02666 02667 void 02668 DoStmt::init(Expression *e) 02669 { 02670 _exprlist.modify(DO_INIT, e); 02671 build_refs(); 02672 } 02673 02674 void 02675 DoStmt::limit(Expression *e) 02676 { 02677 _exprlist.modify(DO_LIMIT, e); 02678 build_refs(); 02679 } 02680 02681 void 02682 DoStmt::step(Expression *e) 02683 { 02684 _exprlist.modify(DO_STEP, e); 02685 build_refs(); 02686 } 02687 02688 DoStmt::DoStmt(const char *l) 02689 : Statement(l, DO_STMT) 02690 { 02691 _exprlist.make_static_list(4); 02692 _exprlist.modify(DO_INDEX, omega()); 02693 _exprlist.modify(DO_INIT, omega()); 02694 _exprlist.modify(DO_LIMIT, omega()); 02695 _exprlist.modify(DO_STEP, omega()); 02696 02697 _follow = NULL; 02698 02699 _target_label = 0; 02700 } 02701 02702 DoStmt::DoStmt(const char *l, Expression *index_exp, Expression *init_exp, 02703 Expression *limit_exp, Expression *step_exp) 02704 : Statement(l, DO_STMT) 02705 { 02706 _exprlist.make_static_list(4); 02707 02708 _follow = NULL; 02709 02710 _target_label = 0; 02711 02712 p_assert(index_exp->op() == ID_OP, "DoStmt( ): 'index' must be an IDExpr"); 02713 02714 _exprlist.modify(DO_INDEX, null_to_omega(index_exp)); 02715 _exprlist.modify(DO_INIT, null_to_omega(init_exp)); 02716 _exprlist.modify(DO_LIMIT, null_to_omega(limit_exp)); 02717 _exprlist.modify(DO_STEP, null_to_omega(step_exp)); 02718 02719 build_refs(); 02720 } 02721 02722 DoStmt::DoStmt(const DoStmt & stmt) 02723 : Statement(stmt.tag(), DO_STMT) 02724 { 02725 copy_base(stmt); 02726 02727 _follow = stmt._follow; 02728 02729 _target_label = stmt._target_label; 02730 02731 _exprlist.modify(DO_INDEX, stmt._exprlist[DO_INDEX].clone() ); 02732 _exprlist.modify(DO_INIT , stmt._exprlist[DO_INIT ].clone() ); 02733 _exprlist.modify(DO_LIMIT, stmt._exprlist[DO_LIMIT].clone() ); 02734 02735 if (stmt._exprlist.valid(DO_STEP)) 02736 _exprlist.modify(DO_STEP, stmt._exprlist[DO_STEP].clone() ); 02737 02738 build_refs(); 02739 } 02740 02741 02742 DoStmt & 02743 DoStmt::operator = (const DoStmt & stmt) 02744 { 02745 copy_base(stmt); 02746 02747 _follow = stmt._follow; 02748 02749 _target_label = stmt._target_label; 02750 02751 _exprlist.modify(DO_INDEX, stmt._exprlist[DO_INDEX].clone() ); 02752 _exprlist.modify(DO_INIT , stmt._exprlist[DO_INIT ].clone() ); 02753 _exprlist.modify(DO_LIMIT, stmt._exprlist[DO_LIMIT].clone() ); 02754 02755 if (stmt._exprlist.valid(DO_STEP)) 02756 _exprlist.modify(DO_STEP, stmt._exprlist[DO_STEP].clone() ); 02757 else 02758 _exprlist.modify(DO_STEP, NULL); 02759 02760 build_refs(); 02761 02762 return *this; 02763 } 02764 02765 Statement * 02766 DoStmt::clone() const 02767 { 02768 return new DoStmt(*this); 02769 } 02770 02771 DoStmt::~DoStmt() 02772 { 02773 /// ... nothing to do 02774 } 02775 02776 02777 void 02778 DoStmt::fortran_write(ostream & o, 02779 int & indent, 02780 char * NOTUSED(type)) const 02781 { 02782 fortran_indent( o, indent ); 02783 02784 02785 if ((switch_value( "output_lang" ) == DT_CEDAR_FORTRAN) && 02786 this->marked_parallel() ) { 02787 o << "XDOALL "; 02788 } 02789 else { 02790 o << "DO "; 02791 } 02792 print_expr_ptr(o, &_exprlist[DO_INDEX]); 02793 o << " = "; 02794 print_expr_ptr(o, &_exprlist[DO_INIT]); 02795 o << ", "; 02796 print_expr_ptr(o, &_exprlist[DO_LIMIT]); 02797 02798 if (_exprlist.valid(DO_STEP)) 02799 o << ", " << _exprlist[DO_STEP]; 02800 02801 ++indent; 02802 02803 } 02804 02805 void 02806 DoStmt::print_debug(ostream & o, int debug) const 02807 { 02808 if (debug) { 02809 o << " {"; /// ... comment '}' 02810 if (_follow) 02811 o << " follow = " << _follow->tag() << ", "; 02812 else 02813 o << " follow = UNDEF, "; 02814 } 02815 else { 02816 o << "DO "; 02817 print_expr_ptr(o, &_exprlist[DO_INDEX]); 02818 o << " = "; 02819 print_expr_ptr(o, &_exprlist[DO_INIT]); 02820 o << ", "; 02821 print_expr_ptr(o, &_exprlist[DO_LIMIT]); 02822 02823 if (_exprlist.valid(DO_STEP)) 02824 o << ", " << _exprlist[DO_STEP]; 02825 } 02826 } 02827 02828 int 02829 DoStmt::structures_OK() const 02830 { 02831 int OK = Statement::in_out_refs_structures_OK(); 02832 02833 return OK; 02834 } 02835 02836 String 02837 DoStmt::get_loop_name() 02838 { 02839 02840 for(Iterator<Assertion> iter = this->assertions(); 02841 iter.valid(); ++iter) { 02842 if (iter.current().type() == AS_LOOPLABEL) { 02843 AssertLoopLabel &a = (AssertLoopLabel &) iter.current(); 02844 p_assert(a.string_arg_list_valid(), 02845 "Loop Label assertion with no valid name"); 02846 p_assert(a.string_arg_list_guarded().entries() == 1, 02847 "Only supporting Loop Label assertions with 1 field"); 02848 /// ... Returns the first LOOPLABEL it finds 02849 return (String) a.string_arg_list_guarded()[0]; 02850 } 02851 } 02852 02853 return (String) ""; 02854 } 02855 02856 RefSet<Symbol> * 02857 DoStmt::private_vars_ref() const 02858 { 02859 RefSet<Symbol> * privates = new RefSet<Symbol>; 02860 02861 for(Iterator<Assertion> iter = this->assertions(); 02862 iter.valid(); 02863 ++iter) { 02864 if (iter.current().type() == AS_PRIVATE) { 02865 if (iter.current().arg_list_valid()) { 02866 for(Iterator<Expression> aiter = 02867 iter.current().arg_list_guarded(); 02868 aiter.valid(); 02869 ++aiter) { 02870 privates->ins(*(aiter.current().base_variable_ref())); 02871 } 02872 } 02873 } 02874 } 02875 return privates; 02876 } 02877 02878 Boolean 02879 DoStmt::marked_parallel() const 02880 { 02881 02882 for(Iterator<Assertion> iter = this->assertions(); 02883 iter.valid(); ++iter) { 02884 if (iter.current().type() == AS_PARALLEL) { 02885 return True; 02886 } 02887 } 02888 02889 return False; 02890 } 02891 02892 Boolean 02893 DoStmt::marked_serial() const 02894 { 02895 02896 for(Iterator<Assertion> iter = this->assertions(); 02897 iter.valid(); ++iter) { 02898 if (iter.current().type() == AS_SERIAL) { 02899 return True; 02900 } 02901 } 02902 02903 return False; 02904 } 02905 02906 void 02907 DoStmt::exchange_convert( VDL &vdl ) 02908 { 02909 Statement::exchange_convert( vdl ); 02910 02911 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 02912 02913 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 02914 02915 BinRep *br = new BinRep( new List<BinRep> ); 02916 br->to_tuple().ins_last( new BinRep( "st" )); 02917 br->to_tuple().ins_last( new BinRep( "DO" )); 02918 S.ins( br ); 02919 02920 br = new BinRep( new List<BinRep> ); 02921 br->to_tuple().ins_last( new BinRep( "index" )); 02922 br->to_tuple().ins_last( new BinRep( this->index().exchange_expr(vdl) )); 02923 S.ins( br ); 02924 02925 br = new BinRep( new List<BinRep> ); 02926 br->to_tuple().ins_last( new BinRep( "init_expr" )); 02927 br->to_tuple().ins_last( new BinRep( this->init().exchange_expr(vdl) )); 02928 S.ins( br ); 02929 02930 br = new BinRep( new List<BinRep> ); 02931 br->to_tuple().ins_last( new BinRep( "limit_expr" )); 02932 br->to_tuple().ins_last( new BinRep( this->limit().exchange_expr(vdl) )); 02933 S.ins( br ); 02934 02935 br = new BinRep( new List<BinRep> ); 02936 br->to_tuple().ins_last( new BinRep( "step_expr" )); 02937 br->to_tuple().ins_last( new BinRep( this->step().exchange_expr(vdl) )); 02938 S.ins( br ); 02939 } 02940 02941 02942 void 02943 DoStmt::convert(BinRep & stmt, ExprTable & etable, 02944 Symtab & NOTUSED(symtab), 02945 const NamelistDict & NOTUSED(namelists), 02946 const FormatDB & NOTUSED(formats), 02947 Dictionary<NextEntry> *next_table) 02948 { 02949 empty_overflow(); 02950 02951 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 02952 List<BinRep> & t = iter.current().to_tuple(); 02953 BinRep & second = t[1]; /// ... The second argument of tuple pairs 02954 String field; 02955 02956 t[0].to_string( field ); 02957 02958 if (!check_common_fields(field, second, etable, next_table, "DoStmt")) { 02959 if (field == "index") 02960 _exprlist.modify(DO_INDEX, 02961 convert_expr(second, etable, "DoStmt")); 02962 else if (field == "init_expr") 02963 _exprlist.modify(DO_INIT, 02964 convert_expr(second, etable, "DoStmt")); 02965 else if (field == "limit_expr") 02966 _exprlist.modify(DO_LIMIT, 02967 convert_expr(second, etable, "DoStmt")); 02968 else if (field == "step_expr") 02969 _exprlist.modify(DO_STEP, 02970 convert_expr(second, etable, "DoStmt")); 02971 else if (field == "target_label") 02972 _target_label = second.to_integer(); 02973 else if (field == "follow") 02974 _follow = temp_stmt_ptr(second); 02975 else if ((field != "prev") && (field != "st")) 02976 make_overflow(iter, "DoStmt"); 02977 } 02978 } 02979 } 02980 02981 02982 int 02983 DoStmt::target_label() const 02984 { 02985 return _target_label; 02986 } 02987 02988 void 02989 DoStmt::target_label(int label) 02990 { 02991 _target_label = label; 02992 } 02993 02994 void 02995 DoStmt::_setptrs(Dictionary<VoidPtrDef> &tags, const FormatDB &formats) 02996 { 02997 Statement::_setptrs(tags, formats); 02998 02999 if (_follow) { 03000 makeptr_ptr(&_follow, tags); 03001 } 03002 } 03003 03004 RefSet<Statement> * 03005 DoStmt::build_succ(const StmtList & NOTUSED(stmts)) const 03006 { 03007 RefSet<Statement> *new_succ = new RefSet<Statement>; 03008 03009 new_succ->ins(*next_ref()); 03010 new_succ->ins(*follow_ref()->next_ref()); 03011 03012 return new_succ; 03013 } 03014 03015 03016 03017 EndDoStmt::EndDoStmt(const char *l) 03018 : Statement(l, ENDDO_STMT) 03019 { 03020 _follow = NULL; 03021 } 03022 03023 EndDoStmt::EndDoStmt(const EndDoStmt & stmt) 03024 : Statement(stmt.tag(), ENDDO_STMT) 03025 { 03026 copy_base(stmt); 03027 _follow = stmt._follow; 03028 } 03029 03030 EndDoStmt & 03031 EndDoStmt::operator = (const EndDoStmt & stmt) 03032 { 03033 copy_base(stmt); 03034 _follow = stmt._follow; 03035 return *this; 03036 } 03037 03038 EndDoStmt::~EndDoStmt() 03039 { 03040 /// ... nothing to do 03041 } 03042 03043 Statement * 03044 EndDoStmt::clone() const 03045 { 03046 return new EndDoStmt(*this); 03047 } 03048 03049 void 03050 EndDoStmt::fortran_write(ostream &o, int &indent, char *NOTUSED(type)) const 03051 { 03052 --indent; 03053 fortran_indent( o, indent ); 03054 03055 /// ... If we are producing Cedar Fortran, and the corresponding 03056 /// ... DO statement was marked parallel, use the corresponding 03057 /// ... type of ENDDO statement 03058 03059 if ((switch_value( "output_lang") == DT_CEDAR_FORTRAN) && 03060 this->outer_ref()->marked_parallel()) { 03061 o << "ENDXDOALL"; 03062 } else { 03063 o << "ENDDO"; 03064 } 03065 } 03066 03067 void 03068 EndDoStmt::print_debug(ostream & o, int debug) const 03069 { 03070 if (!debug) { 03071 o << "ENDDO"; 03072 } 03073 else { 03074 o << " {"; /// ... comment '}' 03075 if (_follow) 03076 o << " follow = " << _follow->tag() << ", "; 03077 else 03078 o << " follow = UNDEF, "; 03079 } 03080 } 03081 03082 int 03083 EndDoStmt::structures_OK() const 03084 { 03085 int OK = Statement::in_out_refs_structures_OK(); 03086 03087 return OK; 03088 } 03089 03090 void 03091 EndDoStmt::exchange_convert( VDL &vdl ) 03092 { 03093 Statement::exchange_convert( vdl ); 03094 03095 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 03096 03097 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 03098 03099 BinRep *br = new BinRep( new List<BinRep> ); 03100 br->to_tuple().ins_last( new BinRep( "st" )); 03101 br->to_tuple().ins_last( new BinRep( "ENDDO" )); 03102 S.ins( br ); 03103 } 03104 03105 03106 void 03107 EndDoStmt::convert(BinRep & stmt, ExprTable & etable, 03108 Symtab & NOTUSED(symtab), 03109 const NamelistDict & NOTUSED(namelists), 03110 const FormatDB & NOTUSED(formats), 03111 Dictionary<NextEntry> *next_table) 03112 { 03113 empty_overflow(); 03114 03115 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 03116 List<BinRep> & t = iter.current().to_tuple(); 03117 BinRep & second = t[1]; /// ... The second argument of tuple pairs 03118 String field; 03119 03120 t[0].to_string( field ); 03121 03122 if (!check_common_fields(field, second, etable, 03123 next_table, "EndDoStmt")) { 03124 if (field == "follow") 03125 _follow = temp_stmt_ptr(second); 03126 else if ((field != "prev") && (field != "st")) 03127 make_overflow(iter, "EndDoStmt"); 03128 } 03129 } 03130 } 03131 03132 void 03133 EndDoStmt::_setptrs(Dictionary<VoidPtrDef> &tags, const FormatDB &formats) 03134 { 03135 Statement::_setptrs(tags, formats); 03136 03137 if (_follow) { 03138 makeptr_ptr(&_follow, tags); 03139 } 03140 } 03141 03142 RefSet<Statement> * 03143 EndDoStmt::build_succ(const StmtList & NOTUSED(stmt)) const 03144 { 03145 RefSet<Statement> *new_succ = new RefSet<Statement>; 03146 03147 new_succ->ins(*follow_ref()); 03148 03149 return new_succ; 03150 } 03151 03152 03153 03154 void 03155 IfStmt::build_refs() 03156 { 03157 /// ... _in_refs and _act_refs come from the If expression 03158 03159 _in_refs.clear(); 03160 _add_in_refs(this->expr()); 03161 03162 _act_refs.clear(); 03163 _add_act_refs(this->expr()); 03164 03165 /// ... _out_refs are just the same as the act_refs 03166 03167 _out_refs = _act_refs; 03168 } 03169 03170 void 03171 IfStmt::expr(Expression *e) 03172 { 03173 _exprlist.modify(IF_EXPR, e); 03174 build_refs(); 03175 } 03176 03177 IfStmt::IfStmt(const char *l) 03178 : Statement(l, IF_STMT) 03179 { 03180 _exprlist.make_static_list(1); 03181 _exprlist.modify(IF_EXPR, omega()); 03182 03183 _follow = NULL; 03184 _matching_endif = NULL; 03185 } 03186 03187 IfStmt::IfStmt(const char *l, Expression * expr_exp) 03188 : Statement(l, IF_STMT) 03189 { 03190 _exprlist.make_static_list(1); 03191 03192 _follow = NULL; 03193 _matching_endif = NULL; 03194 03195 _exprlist.modify(IF_EXPR, null_to_omega(expr_exp)); 03196 03197 build_refs(); 03198 } 03199 03200 IfStmt::IfStmt(const IfStmt & stmt) 03201 : Statement(stmt.tag(), IF_STMT) 03202 { 03203 copy_base(stmt); 03204 03205 _follow = stmt._follow; 03206 _matching_endif = stmt._matching_endif; 03207 03208 _exprlist.modify(IF_EXPR, stmt._exprlist[IF_EXPR].clone() ); 03209 03210 build_refs(); 03211 } 03212 03213 IfStmt & 03214 IfStmt::operator = (const IfStmt & stmt) 03215 { 03216 copy_base(stmt); 03217 03218 _follow = stmt._follow; 03219 _matching_endif = stmt._matching_endif; 03220 03221 _exprlist.modify(IF_EXPR, stmt._exprlist[IF_EXPR].clone() ); 03222 03223 build_refs(); 03224 03225 return *this; 03226 } 03227 03228 Statement * 03229 IfStmt::clone() const 03230 { 03231 return new IfStmt(*this); 03232 } 03233 03234 IfStmt::~IfStmt() 03235 { 03236 /// ... nothing to do 03237 } 03238 03239 void 03240 IfStmt::fortran_write(ostream & o, 03241 int & indent, 03242 char * NOTUSED(type)) const 03243 { 03244 fortran_indent( o, indent ); 03245 03246 o << "IF ("; 03247 print_expr_ptr(o, &_exprlist[IF_EXPR]); 03248 o << ") THEN"; 03249 ++indent; 03250 } 03251 03252 void 03253 IfStmt::print_debug(ostream & o, int debug) const 03254 { 03255 if (!debug) { 03256 o << "IF ("; 03257 print_expr_ptr(o, &_exprlist[IF_EXPR]); 03258 o << ") THEN"; 03259 } 03260 else { 03261 o << " {"; /// ... comment '}' 03262 if (_follow) 03263 o << " follow = " << _follow->tag() << ", "; 03264 else 03265 o << " follow = UNDEF, "; 03266 if (_matching_endif) 03267 o << " matching_endif = " << _matching_endif->tag() << ", "; 03268 else 03269 o << " matching_endif = UNDEF, "; 03270 } 03271 } 03272 03273 int 03274 IfStmt::structures_OK() const 03275 { 03276 int OK = Statement::in_out_refs_structures_OK(); 03277 03278 return OK; 03279 } 03280 03281 void 03282 IfStmt::exchange_convert( VDL &vdl ) 03283 { 03284 Statement::exchange_convert( vdl ); 03285 03286 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 03287 03288 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 03289 03290 BinRep *br = new BinRep( new List<BinRep> ); 03291 br->to_tuple().ins_last( new BinRep( "st" )); 03292 br->to_tuple().ins_last( new BinRep( "IF" )); 03293 S.ins( br ); 03294 03295 br = new BinRep( new List<BinRep> ); 03296 br->to_tuple().ins_last( new BinRep( "expr" )); 03297 br->to_tuple().ins_last( new BinRep( this->expr().exchange_expr(vdl) )); 03298 S.ins( br ); 03299 } 03300 03301 03302 void 03303 IfStmt::convert(BinRep & stmt, ExprTable & etable, 03304 Symtab & NOTUSED(symtab), 03305 const NamelistDict & NOTUSED(namelists), 03306 const FormatDB & NOTUSED(formats), 03307 Dictionary<NextEntry> *next_table) 03308 { 03309 empty_overflow(); 03310 03311 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 03312 List<BinRep> & t = iter.current().to_tuple(); 03313 BinRep & second = t[1]; /// ... The second argument of tuple pairs 03314 String field; 03315 03316 t[0].to_string( field ); 03317 03318 if (!check_common_fields(field, second, etable, 03319 next_table, "IfStmt")) { 03320 if (field == "follow") 03321 _follow = temp_stmt_ptr(second); 03322 else if (field == "expr") 03323 _exprlist.modify(IF_EXPR, 03324 convert_expr(second, etable, "IfStmt")); 03325 else if ((field != "prev") && (field != "st")) 03326 make_overflow(iter, "IfStmt"); 03327 } 03328 } 03329 } 03330 03331 void 03332 IfStmt::_setptrs(Dictionary<VoidPtrDef> &tags, const FormatDB &formats) 03333 { 03334 Statement::_setptrs(tags, formats); 03335 03336 if (_follow) { 03337 makeptr_ptr(&_follow, tags); 03338 } 03339 } 03340 03341 RefSet<Statement> * 03342 IfStmt::build_succ(const StmtList & NOTUSED(stmt)) const 03343 { 03344 RefSet<Statement> *new_succ = new RefSet<Statement>; 03345 03346 new_succ->ins(*next_ref()); 03347 new_succ->ins(*follow_ref()); 03348 03349 return new_succ; 03350 } 03351 03352 03353 03354 void 03355 ElseIfStmt::build_refs() 03356 { 03357 /// ... _in_refs and _act_refs come from the If expression 03358 03359 _in_refs.clear(); 03360 _add_in_refs(this->expr()); 03361 03362 _act_refs.clear(); 03363 _add_act_refs(this->expr()); 03364 03365 /// ... _out_refs are just the same as the act_refs 03366 03367 _out_refs = _act_refs; 03368 } 03369 03370 void 03371 ElseIfStmt::expr(Expression *e) 03372 { 03373 _exprlist.modify(ELSEIF_EXPR, e); 03374 build_refs(); 03375 } 03376 03377 ElseIfStmt::ElseIfStmt(const char *l) 03378 : Statement(l, ELSEIF_STMT) 03379 { 03380 _exprlist.make_static_list(1); 03381 _exprlist.modify(ELSEIF_EXPR, omega()); 03382 03383 _follow = NULL; 03384 _lead = NULL; 03385 } 03386 03387 ElseIfStmt::ElseIfStmt(const char *l, Expression * expr_exp) 03388 : Statement(l, ELSEIF_STMT) 03389 { 03390 _exprlist.make_static_list(1); 03391 03392 _follow = NULL; 03393 _lead = NULL; 03394 03395 _exprlist.modify(ELSEIF_EXPR, null_to_omega(expr_exp)); 03396 03397 build_refs(); 03398 } 03399 03400 ElseIfStmt::ElseIfStmt(const ElseIfStmt & stmt) 03401 : Statement(stmt.tag(), ELSEIF_STMT) 03402 { 03403 copy_base(stmt); 03404 03405 _follow = stmt._follow; 03406 _lead = stmt._lead; 03407 03408 _exprlist.modify(ELSEIF_EXPR, stmt._exprlist[ELSEIF_EXPR].clone() ); 03409 03410 build_refs(); 03411 } 03412 03413 ElseIfStmt & 03414 ElseIfStmt::operator = (const ElseIfStmt & stmt) 03415 { 03416 copy_base(stmt); 03417 03418 _follow = stmt._follow; 03419 _lead = stmt._lead; 03420 03421 _exprlist.modify(ELSEIF_EXPR, stmt._exprlist[ELSEIF_EXPR].clone() ); 03422 03423 build_refs(); 03424 03425 return *this; 03426 } 03427 03428 Statement * 03429 ElseIfStmt::clone() const 03430 { 03431 return new ElseIfStmt(*this); 03432 } 03433 03434 ElseIfStmt::~ElseIfStmt() 03435 { 03436 /// ... nothing to do 03437 } 03438 03439 void 03440 ElseIfStmt::fortran_write(ostream & o, 03441 int & indent, 03442 char * NOTUSED(type)) const 03443 { 03444 --indent; 03445 fortran_indent( o, indent ); 03446 03447 o << "ELSEIF ("; 03448 print_expr_ptr(o, &_exprlist[ELSEIF_EXPR]); 03449 o << ") THEN "; 03450 03451 ++indent; 03452 } 03453 03454 void 03455 ElseIfStmt::print_debug(ostream & o, int debug) const 03456 { 03457 if (!debug) { 03458 o << "ELSEIF ("; 03459 print_expr_ptr(o, &_exprlist[ELSEIF_EXPR]); 03460 o << ") THEN"; 03461 } 03462 else { 03463 o << " {"; /// ... comment '}' 03464 if (_follow) 03465 o << " follow = " << _follow->tag() << ", "; 03466 else 03467 o << " follow = UNDEF, "; 03468 if (_lead) 03469 o << "lead = " << _lead->tag() << ", "; 03470 else 03471 o << "lead = UNDEF, "; 03472 } 03473 } 03474 03475 int 03476 ElseIfStmt::structures_OK() const 03477 { 03478 int OK = Statement::in_out_refs_structures_OK(); 03479 03480 return OK; 03481 } 03482 03483 void 03484 ElseIfStmt::exchange_convert( VDL &vdl ) 03485 { 03486 Statement::exchange_convert( vdl ); 03487 03488 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 03489 03490 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 03491 03492 BinRep *br = new BinRep( new List<BinRep> ); 03493 br->to_tuple().ins_last( new BinRep( "st" )); 03494 br->to_tuple().ins_last( new BinRep( "ELSEIF" )); 03495 S.ins( br ); 03496 03497 br = new BinRep( new List<BinRep> ); 03498 br->to_tuple().ins_last( new BinRep( "expr" )); 03499 br->to_tuple().ins_last( new BinRep( this->expr().exchange_expr(vdl) )); 03500 S.ins( br ); 03501 } 03502 03503 03504 void 03505 ElseIfStmt::convert(BinRep & stmt, ExprTable & etable, 03506 Symtab & NOTUSED(symtab), 03507 const NamelistDict & NOTUSED(namelists), 03508 const FormatDB & NOTUSED(formats), 03509 Dictionary<NextEntry> *next_table) 03510 { 03511 empty_overflow(); 03512 03513 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 03514 List<BinRep> & t = iter.current().to_tuple(); 03515 BinRep & second = t[1]; /// ... The second argument of tuple pairs 03516 String field; 03517 03518 t[0].to_string( field ); 03519 03520 if (!check_common_fields(field, second, etable, 03521 next_table, "ElseIfStmt")) { 03522 if (field == "follow") 03523 _follow = temp_stmt_ptr(second); 03524 else if (field == "expr") 03525 _exprlist.modify(ELSEIF_EXPR, 03526 convert_expr(second, etable, "ElseIfStmt")); 03527 else if ((field != "prev") && (field != "st")) 03528 make_overflow(iter, "ElseIfStmt"); 03529 } 03530 } 03531 } 03532 03533 void 03534 ElseIfStmt::_setptrs(Dictionary<VoidPtrDef> &tags, const FormatDB &formats) 03535 { 03536 Statement::_setptrs(tags, formats); 03537 03538 if (_follow) { 03539 makeptr_ptr(&_follow, tags); 03540 } 03541 } 03542 03543 RefSet<Statement> * 03544 ElseIfStmt::build_succ(const StmtList & NOTUSED(stmts)) const 03545 { 03546 RefSet<Statement> *new_succ = new RefSet<Statement>; 03547 03548 new_succ->ins(*next_ref()); 03549 new_succ->ins(*follow_ref()); 03550 03551 return new_succ; 03552 } 03553 03554 03555 03556 ImpliedGotoStmt::ImpliedGotoStmt(const char *l) 03557 : Statement(l, IMPLIED_GOTO_STMT) 03558 { 03559 _follow = NULL; 03560 } 03561 03562 ImpliedGotoStmt::ImpliedGotoStmt(const ImpliedGotoStmt & stmt) 03563 : Statement(stmt.tag(), IMPLIED_GOTO_STMT) 03564 { 03565 copy_base(stmt); 03566 _follow = stmt._follow; 03567 } 03568 03569 ImpliedGotoStmt & 03570 ImpliedGotoStmt::operator = (const ImpliedGotoStmt & stmt) 03571 { 03572 copy_base(stmt); 03573 _follow = stmt._follow; 03574 03575 return *this; 03576 } 03577 03578 Statement * 03579 ImpliedGotoStmt::clone() const 03580 { 03581 return new ImpliedGotoStmt(*this); 03582 } 03583 03584 ImpliedGotoStmt::~ImpliedGotoStmt() 03585 { 03586 /// ... nothing to do 03587 } 03588 03589 void 03590 ImpliedGotoStmt::fortran_write(ostream & NOTUSED(o), 03591 int & NOTUSED(indent), 03592 char * NOTUSED(type)) const 03593 { 03594 /// ... nothing to do 03595 } 03596 03597 void 03598 ImpliedGotoStmt::print_debug(ostream & o, int debug) const 03599 { 03600 if (!debug) 03601 o << "IMPLIED_GOTO "; 03602 else { 03603 o << " {"; /// ... comment '}' 03604 if (_follow) 03605 o << " follow = " << _follow->tag() << ", "; 03606 else 03607 o << " follow = UNDEF, "; 03608 } 03609 } 03610 03611 int 03612 ImpliedGotoStmt::structures_OK() const 03613 { 03614 int OK = Statement::in_out_refs_structures_OK(); 03615 03616 return OK; 03617 } 03618 03619 void 03620 ImpliedGotoStmt::exchange_convert( VDL &vdl ) 03621 { 03622 Statement::exchange_convert( vdl ); 03623 03624 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 03625 03626 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 03627 03628 BinRep *br = new BinRep( new List<BinRep> ); 03629 br->to_tuple().ins_last( new BinRep( "st" )); 03630 br->to_tuple().ins_last( new BinRep( "IMPLIED_GOTO" )); 03631 S.ins( br ); 03632 } 03633 03634 03635 void 03636 ImpliedGotoStmt::convert(BinRep & stmt, ExprTable & etable, 03637 Symtab & NOTUSED(symtab), 03638 const NamelistDict & NOTUSED(namelists), 03639 const FormatDB & NOTUSED(formats), 03640 Dictionary<NextEntry> *next_table) 03641 { 03642 empty_overflow(); 03643 03644 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 03645 List<BinRep> & t = iter.current().to_tuple(); 03646 BinRep & second = t[1]; /// ... The second argument of tuple pairs 03647 String field; 03648 03649 t[0].to_string( field ); 03650 03651 if (!check_common_fields(field, second, etable, 03652 next_table, "ImpliedGotoStmt")) { 03653 if (field == "follow") 03654 _follow = temp_stmt_ptr(second); 03655 else if ((field != "prev") && (field != "st")) 03656 make_overflow(iter, "ImpliedGotoStmt"); 03657 } 03658 } 03659 } 03660 03661 void 03662 ImpliedGotoStmt::_setptrs(Dictionary<VoidPtrDef> &tags, 03663 const FormatDB &formats) 03664 { 03665 Statement::_setptrs(tags, formats); 03666 03667 if (_follow) { 03668 makeptr_ptr(&_follow, tags); 03669 } 03670 } 03671 03672 RefSet<Statement> * 03673 ImpliedGotoStmt::build_succ(const StmtList & NOTUSED(stmts)) const 03674 { 03675 RefSet<Statement> *new_succ = new RefSet<Statement>; 03676 03677 new_succ->ins(*(this->follow_ref())); 03678 03679 return new_succ; 03680 } 03681 03682 03683 03684 EndIfStmt::EndIfStmt(const char *l) 03685 : Statement(l, ENDIF_STMT) 03686 { 03687 _matching_if = NULL; 03688 _lead = NULL; 03689 } 03690 03691 EndIfStmt::EndIfStmt(const EndIfStmt & stmt) 03692 : Statement(stmt.tag(), ENDIF_STMT) 03693 { 03694 copy_base(stmt); 03695 _matching_if = stmt._matching_if; 03696 _lead = stmt._lead; 03697 } 03698 03699 EndIfStmt & 03700 EndIfStmt::operator = (const EndIfStmt & stmt) 03701 { 03702 copy_base(stmt); 03703 _matching_if = stmt._matching_if; 03704 _lead = stmt._lead; 03705 return *this; 03706 } 03707 03708 Statement * 03709 EndIfStmt::clone() const 03710 { 03711 return new EndIfStmt(*this); 03712 } 03713 03714 EndIfStmt::~EndIfStmt() 03715 { 03716 /// ... nothing to do 03717 } 03718 03719 void 03720 EndIfStmt::fortran_write(ostream & o, 03721 int & indent, 03722 char * NOTUSED(type)) const 03723 { 03724 --indent; 03725 fortran_indent( o, indent ); 03726 03727 o << "ENDIF "; 03728 } 03729 03730 03731 void 03732 EndIfStmt::print_debug(ostream & o, int debug) const 03733 { 03734 if (!debug) 03735 o << "ENDIF "; 03736 else { 03737 o << " {"; /// ... comment '}' 03738 if (_matching_if) 03739 o << " matching_if = " << _matching_if->tag() << ", "; 03740 else 03741 o << " matching_if = UNDEF, "; 03742 if (_matching_if) 03743 o << "lead = " << _matching_if->tag() << ", "; 03744 else 03745 o << "lead = UNDEF, "; 03746 } 03747 } 03748 03749 int 03750 EndIfStmt::structures_OK() const 03751 { 03752 int OK = Statement::in_out_refs_structures_OK(); 03753 03754 return OK; 03755 } 03756 03757 void 03758 EndIfStmt::exchange_convert( VDL &vdl ) 03759 { 03760 Statement::exchange_convert( vdl ); 03761 03762 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 03763 03764 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 03765 03766 BinRep *br = new BinRep( new List<BinRep> ); 03767 br->to_tuple().ins_last( new BinRep( "st" )); 03768 br->to_tuple().ins_last( new BinRep( "ENDIF" )); 03769 S.ins( br ); 03770 } 03771 03772 03773 void 03774 EndIfStmt::convert(BinRep & stmt, ExprTable & etable, 03775 Symtab & NOTUSED(symtab), 03776 const NamelistDict & NOTUSED(namelists), 03777 const FormatDB & NOTUSED(formats), 03778 Dictionary<NextEntry> *next_table) 03779 { 03780 empty_overflow(); 03781 03782 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 03783 List<BinRep> & t = iter.current().to_tuple(); 03784 BinRep & second = t[1]; /// ... The second argument of tuple pairs 03785 String field; 03786 03787 t[0].to_string( field ); 03788 03789 if (!check_common_fields(field, second, etable, 03790 next_table, "EndIfStmt")) { 03791 if ((field != "prev") && (field != "st") && (field != "lead")) 03792 make_overflow(iter, "EndIfStmt"); 03793 } 03794 } 03795 } 03796 03797 03798 03799 ElseStmt::ElseStmt(const char *l) 03800 : Statement(l, ELSE_STMT) 03801 { 03802 _follow = NULL; 03803 _lead = NULL; 03804 } 03805 03806 ElseStmt::ElseStmt(const ElseStmt & stmt) 03807 : Statement(stmt.tag(), ELSE_STMT) 03808 { 03809 copy_base(stmt); 03810 _follow = stmt._follow; 03811 _lead = stmt._lead; 03812 } 03813 03814 ElseStmt & 03815 ElseStmt::operator = (const ElseStmt & stmt) 03816 { 03817 copy_base(stmt); 03818 _follow = stmt._follow; 03819 _lead = stmt._lead; 03820 return *this; 03821 } 03822 03823 Statement * 03824 ElseStmt::clone() const 03825 { 03826 return new ElseStmt(*this); 03827 } 03828 03829 ElseStmt::~ElseStmt() 03830 { 03831 /// ... nothing to do 03832 } 03833 03834 void 03835 ElseStmt::fortran_write(ostream & o, 03836 int & indent, 03837 char * NOTUSED(type)) const 03838 { 03839 --indent; 03840 fortran_indent( o, indent ); 03841 03842 o << "ELSE "; 03843 03844 ++indent; 03845 } 03846 03847 void 03848 ElseStmt::print_debug(ostream & o, int debug) const 03849 { 03850 if (!debug) 03851 o << "ELSE "; 03852 else { 03853 o << " {"; /// ... comment '}' 03854 if (_follow) 03855 o << " follow = " << _follow->tag() << ", "; 03856 else 03857 o << " follow = UNDEF, "; 03858 if (_lead) 03859 o << "lead = " << _lead->tag() << ", "; 03860 else 03861 o << "lead = UNDEF, "; 03862 } 03863 } 03864 03865 int 03866 ElseStmt::structures_OK() const 03867 { 03868 int OK = Statement::in_out_refs_structures_OK(); 03869 03870 return OK; 03871 } 03872 03873 void 03874 ElseStmt::exchange_convert( VDL &vdl ) 03875 { 03876 Statement::exchange_convert( vdl ); 03877 03878 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 03879 03880 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 03881 03882 BinRep *br = new BinRep( new List<BinRep> ); 03883 br->to_tuple().ins_last( new BinRep( "st" )); 03884 br->to_tuple().ins_last( new BinRep( "ELSE" )); 03885 S.ins( br ); 03886 } 03887 03888 03889 void 03890 ElseStmt::convert(BinRep & stmt, ExprTable & etable, 03891 Symtab & NOTUSED(symtab), 03892 const NamelistDict & NOTUSED(namelists), 03893 const FormatDB & NOTUSED(formats), 03894 Dictionary<NextEntry> *next_table) 03895 { 03896 empty_overflow(); 03897 03898 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 03899 List<BinRep> & t = iter.current().to_tuple(); 03900 BinRep & second = t[1]; /// ... The second argument of tuple pairs 03901 String field; 03902 03903 t[0].to_string( field ); 03904 03905 if (!check_common_fields(field, second, etable, 03906 next_table, "ElseStmt")) { 03907 if (field == "follow") 03908 _follow = temp_stmt_ptr(second); 03909 else if ((field != "prev") && (field != "st") && (field != "lead")) 03910 make_overflow(iter, "ElseStmt"); 03911 } 03912 } 03913 } 03914 03915 void 03916 ElseStmt::_setptrs(Dictionary<VoidPtrDef> &tags, const FormatDB &formats) 03917 { 03918 Statement::_setptrs(tags, formats); 03919 03920 if (_follow) { 03921 makeptr_ptr(&_follow, tags); 03922 } 03923 } 03924 03925 RefSet<Statement> * 03926 ElseStmt::build_succ(const StmtList & NOTUSED(stmts)) const 03927 { 03928 RefSet<Statement> *new_succ = new RefSet<Statement>; 03929 03930 new_succ->ins(*next_ref()); 03931 03932 /// ... The ELSE statement does not flow to the ENDIF. This causes problems 03933 /// ... with the constant propagation and the privatization. 03934 // 03935 /// ... But, if it did use the following line. 03936 /// ... new_succ->ins(*follow_ref()); 03937 03938 return new_succ; 03939 } 03940 03941 03942 03943 void 03944 AssignStmt::relink_sptrs(ProgramUnit &p) 03945 { 03946 /// ... Relink format pointer 03947 03948 if (this->atype() == FORMAT_ASSIGN) { 03949 int label = this->format_ref()->value(); 03950 this->format(p.formats().find_ref(label)); 03951 } 03952 } 03953 03954 void 03955 AssignStmt::build_refs() 03956 { 03957 /// ... _in_refs and _act_refs can only occur if we are assigning an array, 03958 /// ... via the subscripting expressions 03959 03960 _in_refs.clear(); 03961 if (this->lhs().op() == ARRAY_REF_OP) 03962 _add_in_refs(this->lhs().subscript()); 03963 else if (this->lhs().op() == SUBSTRING_OP) 03964 _add_in_refs(this->lhs().bound()); 03965 03966 _act_refs.clear(); 03967 if (this->lhs().op() == ARRAY_REF_OP) 03968 _add_act_refs(this->lhs().subscript()); 03969 else if (this->lhs().op() == SUBSTRING_OP) 03970 _add_act_refs(this->lhs().bound()); 03971 03972 /// ... _out_refs are the act_refs plus the left-hand side expression 03973 03974 _out_refs = _act_refs; 03975 _out_refs.ins(this->lhs()); 03976 } 03977 03978 AssignStmt::AssignStmt(const char *l) 03979 : Statement(l, ASSIGN_STMT) 03980 { 03981 _exprlist.make_static_list(1); 03982 _exprlist.modify(LHS, omega()); 03983 03984 _target = NULL; 03985 } 03986 03987 AssignStmt::AssignStmt(const char *l, Expression *lhs_exp, 03988 Statement *target_stmt) 03989 : Statement(l, ASSIGN_STMT) 03990 { 03991 p_assert(target_stmt->stmt_class() == LABEL_STMT, 03992 "AssignStmt( ): the target statement must be a LabelStmt"); 03993 03994 _exprlist.make_static_list(1); 03995 03996 _exprlist.modify(LHS, null_to_omega(lhs_exp)); 03997 03998 _target = target_stmt; 03999 _format = 0; 04000 _atype = EXECUTABLE_ASSIGN; 04001 04002 build_refs(); 04003 } 04004 04005 AssignStmt::AssignStmt(const AssignStmt & stmt) 04006 : Statement(stmt.tag(), ASSIGN_STMT) 04007 { 04008 copy_base(stmt); 04009 04010 _target = stmt._target; 04011 _format = stmt._format; 04012 _atype = stmt._atype; 04013 04014 _exprlist.modify(LHS, stmt._exprlist[LHS].clone() ); 04015 04016 build_refs(); 04017 } 04018 04019 AssignStmt & 04020 AssignStmt::operator = (const AssignStmt & stmt) 04021 { 04022 copy_base(stmt); 04023 04024 _target = stmt._target; 04025 _format = stmt._format; 04026 _atype = stmt._atype; 04027 04028 _exprlist.modify(LHS, stmt._exprlist[LHS].clone() ); 04029 04030 build_refs(); 04031 04032 return *this; 04033 } 04034 04035 Statement * 04036 AssignStmt::clone() const 04037 { 04038 return new AssignStmt(*this); 04039 } 04040 04041 AssignStmt::~AssignStmt() 04042 { 04043 /// ... nothing to do 04044 } 04045 04046 void 04047 AssignStmt::lhs(Expression *ex) 04048 { 04049 _exprlist.modify(LHS, ex); 04050 build_refs(); 04051 } 04052 04053 void 04054 AssignStmt::atype(ASSIGN_TYPE t) 04055 { 04056 _atype = t; 04057 } 04058 04059 void 04060 AssignStmt::target(Statement *t) 04061 { 04062 if (t != 0) { 04063 p_assert(t->stmt_class() == LABEL_STMT, 04064 "AssignStmt::target(Statement *) LabelStmt expected"); 04065 } 04066 04067 _target = t; 04068 } 04069 04070 void 04071 AssignStmt::format(const Format *f) 04072 { 04073 _format = f->clone(); 04074 } 04075 04076 void 04077 AssignStmt::fortran_write(ostream & o, 04078 int & indent, 04079 char * NOTUSED(type)) const 04080 { 04081 fortran_indent( o, indent ); 04082 04083 o << "ASSIGN "; 04084 if (_atype == EXECUTABLE_ASSIGN) { 04085 if (_target) 04086 o << _target->value(); 04087 else 04088 o << "<UNDEF>"; 04089 } else { 04090 if (_format) 04091 o << _format->value(); 04092 else 04093 o << "<UNDEF>"; 04094 } 04095 04096 o << " TO "; 04097 print_expr_ptr(o, &_exprlist[LHS]); 04098 } 04099 04100 void 04101 AssignStmt::print_debug(ostream & o, int debug) const 04102 { 04103 if (!debug) { 04104 o << "ASSIGN "; 04105 if (_atype == EXECUTABLE_ASSIGN) { 04106 if (_target) 04107 o << _target->value(); 04108 else 04109 o << "<UNDEF>"; 04110 } else { 04111 if (_format) 04112 o << _format->value() << "[ " << _format->format_ref() << " ]"; 04113 else 04114 o << "<UNDEF>"; 04115 } 04116 04117 o << " TO "; 04118 print_expr_ptr(o, &_exprlist[LHS]); 04119 } 04120 else 04121 o << " {"; /// ... comment '}' 04122 } 04123 04124 int 04125 AssignStmt::structures_OK() const 04126 { 04127 int OK = Statement::in_out_refs_structures_OK(); 04128 04129 return OK; 04130 } 04131 04132 void 04133 AssignStmt::exchange_convert( VDL &vdl ) 04134 { 04135 Statement::exchange_convert( vdl ); 04136 04137 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 04138 04139 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 04140 04141 BinRep *br = new BinRep( new List<BinRep> ); 04142 br->to_tuple().ins_last( new BinRep( "st" )); 04143 br->to_tuple().ins_last( new BinRep( "ASSIGN" )); 04144 S.ins( br ); 04145 04146 br = new BinRep( new List<BinRep> ); 04147 br->to_tuple().ins_last( new BinRep( "lhs" )); 04148 br->to_tuple().ins_last( new BinRep( this->lhs().exchange_expr(vdl) )); 04149 S.ins( br ); 04150 } 04151 04152 04153 void 04154 AssignStmt::convert(BinRep & stmt, ExprTable & etable, 04155 Symtab & NOTUSED(symtab), 04156 const NamelistDict & NOTUSED(namelists), 04157 const FormatDB & NOTUSED(formats), 04158 Dictionary<NextEntry> *next_table) 04159 { 04160 empty_overflow(); 04161 04162 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 04163 List<BinRep> & t = iter.current().to_tuple(); 04164 BinRep & second = t[1]; /// ... The second argument of tuple pairs 04165 String field; 04166 04167 t[0].to_string( field ); 04168 04169 if (!check_common_fields(field, second, etable, 04170 next_table, "AssignStmt")) { 04171 if (field == "target") 04172 _target = temp_stmt_ptr(second); 04173 else if (field == "lhs") 04174 _exprlist.modify(LHS, 04175 convert_expr(second, etable, "AssignStmt")); 04176 else if ((field != "prev") && (field != "st")) 04177 make_overflow(iter, "AssignStmt"); 04178 } 04179 } 04180 } 04181 04182 void 04183 AssignStmt::_setptrs(Dictionary<VoidPtrDef> &tags, const FormatDB &formats) 04184 { 04185 Statement::_setptrs(tags, formats); 04186 04187 if (_target) { 04188 Boolean ok = makeptr_ptr(&_target, tags); 04189 if (ok) 04190 this->atype(EXECUTABLE_ASSIGN); 04191 else { 04192 this->atype(FORMAT_ASSIGN); 04193 04194 const char *t = _target->tag(); 04195 int label = atoi(t+1); 04196 const Format *f = formats.find_ref(label); 04197 04198 this->format(f); 04199 this->target(0); 04200 } 04201 } 04202 } 04203 04204 04205 04206 void 04207 IOStmt::relink_sptrs(ProgramUnit &p) 04208 { 04209 /// ... Relink all expressions on the s_control list 04210 04211 Iterator<s_control_type> iter = _s_control; 04212 04213 while (iter.valid()) { 04214 iter.current().expr[0].relink_eptrs( p ); 04215 ++iter; 04216 } 04217 } 04218 04219 void 04220 IOStmt::build_refs() 04221 { 04222 /// ... Clear out all sets: 04223 04224 _in_refs.clear(); 04225 _out_refs.clear(); 04226 _act_refs.clear(); 04227 04228 // First, build the in/out/act sets for the IO list 04229 04230 switch (_type) { 04231 case WRITE_STMT: 04232 case PRINT_STMT: 04233 if (io_list_valid()) { 04234 for (Iterator<Expression> iter = io_list_guarded().arg_list(); 04235 iter.valid(); ++iter) { 04236 _add_in_refs(iter.current()); 04237 _add_act_refs(iter.current()); 04238 _add_out_refs(iter.current()); 04239 /// ... Gets any EQUAL_OPs in the iolist 04240 } 04241 } 04242 break; 04243 04244 case READ_STMT: 04245 if (io_list_valid()) { 04246 for (Iterator<Expression> iter = io_list_guarded().arg_list(); 04247 iter.valid(); ++iter) { 04248 _add_ioread_sets (iter.current()); 04249 /// ... Special case where top-level vars 04250 /// ... are assumed to be WRITTEN 04251 } 04252 } 04253 break; 04254 04255 /// ... The following have no IO list: 04256 04257 case OPEN_STMT: 04258 case CLOSE_STMT: 04259 case REWIND_STMT: 04260 case BACKSPACE_STMT: 04261 case ENDFILE_STMT: 04262 case INQUIRE_STMT: 04263 break; 04264 default: break; 04265 } 04266 04267 // Build the in/out/act sets for the control list 04268 04269 for (Iterator<s_control_type> iter = s_control_guarded(); 04270 iter.valid(); ++iter) { 04271 s_control_type &s = iter.current(); 04272 04273 if ((s.keyword == "IOSTAT") || 04274 (s.keyword == "ACCESS") || 04275 (s.keyword == "BLANK") || 04276 (s.keyword == "CARRIAGECONTROL") || 04277 (s.keyword == "DIRECT") || 04278 (s.keyword == "EXIST") || 04279 (s.keyword == "FORM") || 04280 (s.keyword == "FORMATTED") || 04281 (s.keyword == "NAME") || 04282 (s.keyword == "NAMED") || 04283 (s.keyword == "KEYED") || 04284 (s.keyword == "NEXTREC") || 04285 (s.keyword == "OPENED") || 04286 (s.keyword == "ORGANIZATION") || 04287 (s.keyword == "RECL") || 04288 (s.keyword == "RECORDTYPE") || 04289 (s.keyword == "SEQUENTIAL") || 04290 (s.keyword == "UNFORMATTED") || 04291 ((_type == INQUIRE_STMT) && 04292 (s.keyword == "UNIT"))) { 04293 04294 if (s.expr[0].op() == ID_OP) 04295 _out_refs.ins ( s.expr[0] ); 04296 else if (s.expr[0].op() == ARRAY_REF_OP) { 04297 _out_refs.ins ( s.expr[0] ); 04298 _add_in_refs ( s.expr[0].subscript() ); 04299 _add_act_refs ( s.expr[0].subscript() ); 04300 } 04301 else if (s.expr[0].op() == SUBSTRING_OP) { 04302 _out_refs.ins ( s.expr[0] ); 04303 _add_in_refs ( s.expr[0].bound() ); 04304 _add_act_refs ( s.expr[0].bound() ); 04305 } 04306 } 04307 else if (s.keyword == "NML") { 04308 p_assert( _namelist, 04309 "read statement uses NML, but no namelist pointer set"); 04310 04311 if (_type == READ_STMT) { 04312 for (Iterator<Expression> iter3 = _namelist->iolist(); 04313 iter3.valid(); ++iter3) { 04314 _out_refs.ins(iter3.current()); 04315 } 04316 } 04317 else if (_type == WRITE_STMT) { 04318 for (Iterator<Expression> iter3 = _namelist->iolist(); 04319 iter3.valid(); ++iter3) { 04320 _in_refs.ins(iter3.current()); 04321 } 04322 } 04323 } 04324 04325 else { 04326 _add_in_refs ( s.expr[0] ); 04327 _add_act_refs( s.expr[0] ); 04328 } 04329 } 04330 04331 /// ... _out_refs += _act_refs 04332 for (Iterator<Expression> iter2 = _act_refs; iter2.valid(); ++iter2) 04333 _out_refs.ins (iter2.current()); 04334 } 04335 04336 IOStmt::IOStmt(STMT_TYPE st, const char *l) 04337 : Statement(l, st) 04338 { 04339 _exprlist.make_static_list(1); 04340 _exprlist.modify(IO_LIST, omega()); 04341 04342 _namelist = 0; 04343 } 04344 04345 IOStmt::IOStmt(STMT_TYPE st, const char *l, Expression * io_list_exp, 04346 s_control_type * s_1, s_control_type * s_2, s_control_type * s_3, 04347 s_control_type * s_4, s_control_type * s_5, s_control_type * s_6) 04348 : Statement(l, st) 04349 { 04350 p_assert(io_list_exp->op() == COMMA_OP, 04351 "IOStmt( ): 'io_list' must be a CommaExpr"); 04352 04353 _exprlist.make_static_list(1); 04354 _exprlist.modify(IO_LIST, null_to_omega(io_list_exp)); 04355 04356 _namelist = 0; 04357 04358 if (s_1) 04359 _s_control.ins_last(s_1); 04360 if (s_2) 04361 _s_control.ins_last(s_2); 04362 if (s_3) 04363 _s_control.ins_last(s_3); 04364 if (s_4) 04365 _s_control.ins_last(s_4); 04366 if (s_5) 04367 _s_control.ins_last(s_5); 04368 if (s_6) 04369 _s_control.ins_last(s_6); 04370 04371 build_refs(); 04372 } 04373 04374 IOStmt::IOStmt(const IOStmt & stmt) 04375 : Statement(stmt.tag(), stmt._type) 04376 { 04377 copy_base(stmt); 04378 04379 _s_control = stmt._s_control; 04380 04381 _namelist = stmt._namelist; 04382 /// ... Make an alias to the NAMELIST, this does not own the object 04383 04384 if (stmt._exprlist.valid(IO_LIST)) 04385 _exprlist.modify(IO_LIST, stmt._exprlist[IO_LIST].clone() ); 04386 04387 build_refs(); 04388 } 04389 04390 IOStmt & 04391 IOStmt::operator = (const IOStmt & stmt) 04392 { 04393 copy_base(stmt); 04394 04395 _s_control = stmt._s_control; 04396 04397 _namelist = stmt._namelist; 04398 /// ... Make an alias to the NAMELIST, this does not own the object 04399 04400 if (stmt._exprlist.valid(IO_LIST)) 04401 _exprlist.modify(IO_LIST, stmt._exprlist[IO_LIST].clone() ); 04402 else 04403 _exprlist.modify(IO_LIST, NULL); 04404 04405 build_refs(); 04406 04407 return *this; 04408 } 04409 04410 Statement * 04411 IOStmt::clone() const 04412 { 04413 return new IOStmt(*this); 04414 } 04415 04416 IOStmt::~IOStmt() 04417 { 04418 _namelist = 0; 04419 } 04420 04421 void 04422 IOStmt::io_list(Expression *e) 04423 { 04424 p_assert(e->op() == COMMA_OP, 04425 "IOStmt::io_list(Expression *): CommaExpr expected"); 04426 04427 _exprlist.modify(IO_LIST, e); 04428 04429 build_refs(); 04430 } 04431 04432 List<s_control_type> & 04433 IOStmt::s_control_guarded() 04434 { 04435 return (List<s_control_type> &) _s_control; 04436 } 04437 04438 const List<s_control_type> & 04439 IOStmt::s_control_guarded() const 04440 { 04441 return (const List<s_control_type> &) _s_control; 04442 } 04443 04444 int 04445 IOStmt::s_control_valid() const 04446 { 04447 return True; 04448 } 04449 04450 void 04451 IOStmt::fortran_write(ostream & o, 04452 int & indent, 04453 char * NOTUSED(type)) const 04454 { 04455 fortran_indent( o, indent ); 04456 04457 switch (_type) { 04458 case READ_STMT: o << "READ "; break; 04459 case WRITE_STMT: o << "WRITE "; break; 04460 case PRINT_STMT: o << "PRINT "; break; 04461 case OPEN_STMT: o << "OPEN "; break; 04462 case CLOSE_STMT: o << "CLOSE "; break; 04463 case REWIND_STMT: o << "REWIND "; break; 04464 case BACKSPACE_STMT: o << "BACKSPACE "; break; 04465 case ENDFILE_STMT: o << "ENDFILE "; break; 04466 case INQUIRE_STMT: o << "INQUIRE "; break; 04467 default: break; 04468 } 04469 04470 Iterator<s_control_type> iter = CASTAWAY(List<s_control_type> &) _s_control; 04471 04472 if (_type == PRINT_STMT) { 04473 p_assert(iter.valid() && (_s_control.entries() == 1) && 04474 (iter.current().keyword == "FMT"), 04475 "PRINT statement can only have a FMT s_control_type entry"); 04476 o << iter.current().expr[0]; 04477 } 04478 else if (iter.valid()) { 04479 o << "(" ; 04480 04481 s_control_type *s_unit = 0; 04482 s_control_type *s_fmt = 0; 04483 04484 RefList<s_control_type> s_rest; 04485 04486 for ( ; iter.valid(); ++iter) { 04487 if (iter.current().keyword == "UNIT") 04488 s_unit = &iter.current(); 04489 else if (iter.current().keyword == "FMT") 04490 s_fmt = &iter.current(); 04491 else 04492 s_rest.ins_last( iter.current() ); 04493 } 04494 04495 /// ANSI Fortran 77 says you must have exactly ONE unit spec 04496 /// in a parenthesized control info list: READ (<control info list>) . . . 04497 04498 Boolean wrote_something = True; 04499 04500 if (s_unit == 0) { 04501 if (_type != INQUIRE_STMT) { 04502 o << "UNIT = *"; /// ... Represent the default unit 04503 } 04504 else { 04505 wrote_something = False; 04506 } 04507 if (s_fmt != 0) { 04508 s_rest.ins_first( *s_fmt ); 04509 s_fmt = 0; 04510 } 04511 } 04512 else { 04513 o << s_unit->expr[0]; 04514 if (s_fmt != 0) { 04515 o << ", " << s_fmt->expr[0]; 04516 s_fmt = 0; 04517 } 04518 } 04519 04520 iter = s_rest; 04521 04522 if (iter.valid()) { 04523 if (wrote_something) { 04524 o << ", "; 04525 } 04526 iter.current().write(o); 04527 ++iter; 04528 } 04529 for ( ; iter.valid(); ++iter) { 04530 o << ", "; 04531 iter.current().write(o); 04532 } 04533 04534 o << ")"; 04535 } 04536 04537 if (_exprlist.valid(IO_LIST)) { /// ... If there is one, print the IO list 04538 if (_exprlist[IO_LIST].arg_list().entries() > 0) { 04539 o << (_type == PRINT_STMT ? ", " : " "); 04540 _exprlist[IO_LIST].print(o); 04541 } 04542 } 04543 } 04544 04545 void 04546 IOStmt::print_debug(ostream & o, int debug) const 04547 { 04548 if (debug) 04549 o << " {"; /// ... comment '}' 04550 else { 04551 switch (_type) { 04552 case READ_STMT: o << "READ "; break; 04553 case WRITE_STMT: o << "WRITE "; break; 04554 case PRINT_STMT: o << "PRINT "; break; 04555 case OPEN_STMT: o << "OPEN "; break; 04556 case CLOSE_STMT: o << "CLOSE "; break; 04557 case REWIND_STMT: o << "REWIND "; break; 04558 case BACKSPACE_STMT: o << "BACKSPACE "; break; 04559 case ENDFILE_STMT: o << "ENDFILE "; break; 04560 case INQUIRE_STMT: o << "INQUIRE "; break; 04561 default: break; 04562 } 04563 04564 Iterator<s_control_type>iter = (List<s_control_type> &) _s_control; 04565 04566 if (iter.valid()) { 04567 o << "(" << iter.current(); 04568 for (iter.next(); iter.valid(); iter.next()) 04569 o << ", " << iter.current(); 04570 o << ")"; 04571 } 04572 04573 if (_exprlist.valid(IO_LIST)) { /// ... If there is one, print the IO list 04574 o << " "; 04575 _exprlist[IO_LIST].print(o); 04576 } 04577 } 04578 } 04579 04580 04581 int 04582 IOStmt::structures_OK() const 04583 { 04584 int OK = Statement::in_out_refs_structures_OK(); 04585 04586 return OK; 04587 } 04588 04589 void 04590 IOStmt::exchange_convert( VDL &vdl ) 04591 { 04592 Statement::exchange_convert( vdl ); 04593 04594 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 04595 04596 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 04597 String st; 04598 04599 switch (_type) { 04600 case READ_STMT: st = "READ"; break; 04601 case WRITE_STMT: st = "WRITE"; break; 04602 case PRINT_STMT: st = "PRINT"; break; 04603 case OPEN_STMT: st = "OPEN"; break; 04604 case CLOSE_STMT: st = "CLOSE"; break; 04605 case REWIND_STMT: st = "REWIND"; break; 04606 case BACKSPACE_STMT: st = "BACKSPACE"; break; 04607 case ENDFILE_STMT: st = "ENDFILE"; break; 04608 case INQUIRE_STMT: st = "INQUIRE"; break; 04609 default: st = "UNEXPECTED IOSTMT"; break;} 04610 04611 BinRep *br = new BinRep( new List<BinRep> ); 04612 br->to_tuple().ins_last( new BinRep( "st" )); 04613 br->to_tuple().ins_last( new BinRep( st )); 04614 S.ins( br ); 04615 } 04616 04617 04618 /// When converting IO Statements the structure of the s_control field is 04619 /// changed. In SETL, a FMT could be either an index in the expression 04620 /// table (an expression) or a string (an index in the format table). 04621 /// In the C++ version, s_control structs always contain an expression 04622 /// (along with the keyword). This is made possible by a new Expression 04623 /// called FormatExpr which simply contains the string found in SETL. 04624 04625 04626 void 04627 IOStmt::convert(BinRep & stmt, ExprTable & etable, 04628 Symtab & NOTUSED(symtab), 04629 const NamelistDict &namelists, 04630 const FormatDB &formats, 04631 Dictionary<NextEntry> *next_table) 04632 { 04633 empty_overflow(); 04634 04635 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 04636 List<BinRep> & t = iter.current().to_tuple(); 04637 BinRep & second = t[1]; /// ... The second argument of tuple pairs 04638 String field; 04639 04640 t[0].to_string( field ); 04641 04642 if (!check_common_fields(field, second, etable, 04643 next_table, "IOStmt")) { 04644 if (field == "io_list") { 04645 _exprlist.modify(IO_LIST, 04646 convert_expr(second, etable, "IOStmt")); 04647 } 04648 else if (field == "s_control") { 04649 04650 for (Iterator<BinRep> io_iter = second.to_set(); 04651 io_iter.valid(); ++io_iter) { 04652 s_control_type *sc = new s_control_type; 04653 04654 io_iter.current()[0].to_string(sc->keyword); 04655 BinRep & ex = io_iter.current()[1]; 04656 04657 if (ex.is_string()) { 04658 String ex_string; 04659 ex.to_string(ex_string); 04660 04661 if (ex_string[0] == 'F') { 04662 /// ... We have a Format reference, such as 'F201' 04663 /// ... Check to make sure that it is in the correct 04664 /// ... format first 04665 04666 int len = strlen((const char *) ex_string + 1); 04667 04668 for (int i = 1; i < len; ++i) { 04669 p_assert( isdigit(ex_string[i]), 04670 "IOStmt::convert(): Format reference" 04671 " did not follow the format of 'Fxxx'" 04672 " where xxx is non-negative number" ); 04673 } 04674 04675 char *format_tag = 04676 (char *) ((const char *) ex_string) + 1; 04677 04678 int number = atoi(format_tag); 04679 04680 p_assert(number > 0, "Format line number is zero"); 04681 04682 sc->expr.modify(0, 04683 new FormatExpr(*formats.find_ref(number))); 04684 } 04685 else { 04686 /// ... What we want here is a LabelExpr. 04687 /// ... However, we don't yet know what the 04688 /// ... Statement pointer is--we just have its 04689 /// ... tag, which is ex_string. 04690 /// ... So, we'll just create a StmtLabelExpr for 04691 /// ... now and count on the _setptrs() method 04692 /// ... of IOStmt to change it into a LabelExpr. 04693 04694 sc->expr.modify(0, new StmtLabelExpr(ex_string)); 04695 } 04696 } 04697 else if (ex.is_integer()) 04698 sc->expr.modify(0, etable[ex.to_integer()]); 04699 else { 04700 cerr << "IOStmt::convert: " 04701 << "Unrecognized s_control entry in statement " 04702 << _tag << " in " << io_iter.current() << endl; 04703 p_abort( "(see above message)" ); 04704 } 04705 04706 _s_control.ins_last(sc); 04707 04708 if (sc->keyword == "NML") { 04709 _namelist = 04710 CASTAWAY(Namelist *)namelists.find_ref(sc->expr[0].symbol().name_ref()); 04711 } 04712 } 04713 } 04714 else if ((field != "prev") && (field != "st")) { 04715 make_overflow(iter, "IOStmt"); 04716 } 04717 } 04718 } 04719 } 04720 04721 void 04722 IOStmt::_setptrs(Dictionary<VoidPtrDef> &tags, const FormatDB &formats) 04723 { 04724 Statement::_setptrs(tags, formats); 04725 04726 /// ... iterate through s_control: replace all StmtLabelExpr's with 04727 /// ... LabelExpr's 04728 04729 for (Iterator<s_control_type>iter = _s_control; iter.valid(); ++iter) { 04730 if (iter.current().expr[0].op() == STMT_LABEL_OP) { 04731 Expression &stmt_label_expr = iter.current().expr[0]; 04732 Statement &stmt_ref = * (Statement *) 04733 tags[stmt_label_expr.data_ref()].ptr_ref(); 04734 iter.current().expr.modify(0, new LabelExpr(stmt_ref)); 04735 } 04736 } 04737 } 04738 04739 RefSet<Statement> * 04740 IOStmt::build_succ(const StmtList & NOTUSED(stmts)) const 04741 { 04742 RefSet<Statement> *new_succ = new RefSet<Statement>; 04743 04744 new_succ->ins(*next_ref()); 04745 04746 for (Iterator<s_control_type>iter = _s_control; iter.valid(); ++iter) { 04747 if ((iter.current().keyword == "END") || 04748 (iter.current().keyword == "ERR")) { 04749 Expression &label_expr = iter.current().expr[0]; 04750 new_succ->ins(label_expr.stmt()); 04751 } 04752 } 04753 return new_succ; 04754 } 04755 04756 04757 04758 StopStmt::StopStmt(const char *l) 04759 : Statement(l, STOP_STMT) 04760 { 04761 _exprlist.make_static_list(1); 04762 _exprlist.modify(STOP_EXPR, omega()); 04763 } 04764 04765 StopStmt::StopStmt(const char *l, Expression * expr_exp) 04766 : Statement(l, STOP_STMT) 04767 { 04768 _exprlist.make_static_list(1); 04769 04770 _exprlist.modify(STOP_EXPR, null_to_omega(expr_exp)); 04771 } 04772 04773 StopStmt::StopStmt(const StopStmt & stmt) 04774 : Statement(stmt.tag(), STOP_STMT) 04775 { 04776 copy_base(stmt); 04777 if (stmt._exprlist.valid(STOP_EXPR)) 04778 _exprlist.modify(STOP_EXPR, stmt._exprlist[STOP_EXPR].clone() ); 04779 } 04780 04781 StopStmt & 04782 StopStmt::operator = (const StopStmt & stmt) 04783 { 04784 copy_base(stmt); 04785 04786 if (stmt._exprlist.valid(STOP_EXPR)) 04787 _exprlist.modify(STOP_EXPR, stmt._exprlist[STOP_EXPR].clone() ); 04788 else 04789 _exprlist.modify(STOP_EXPR, NULL); 04790 04791 return *this; 04792 } 04793 04794 Statement * 04795 StopStmt::clone() const 04796 { 04797 return new StopStmt(*this); 04798 } 04799 04800 StopStmt::~StopStmt() 04801 { 04802 /// ... nothing to do 04803 } 04804 04805 04806 void 04807 StopStmt::expr(Expression * e) 04808 { 04809 _exprlist.modify(STOP_EXPR, e); 04810 } 04811 04812 void 04813 StopStmt::fortran_write(ostream & o, 04814 int & indent, 04815 char * NOTUSED(type)) const 04816 { 04817 fortran_indent( o, indent ); 04818 04819 o << "STOP "; 04820 if (_exprlist.valid(STOP_EXPR)) 04821 o << _exprlist[STOP_EXPR]; 04822 } 04823 04824 void 04825 StopStmt::print_debug(ostream & o, int debug) const 04826 { 04827 if (debug) 04828 o << " {"; /// ... comment '}' 04829 else { 04830 o << "STOP "; 04831 if (_exprlist.valid(STOP_EXPR)) 04832 o << _exprlist[STOP_EXPR]; 04833 } 04834 } 04835 04836 int 04837 StopStmt::structures_OK() const 04838 { 04839 int OK = Statement::in_out_refs_structures_OK(); 04840 04841 return OK; 04842 } 04843 04844 void 04845 StopStmt::exchange_convert( VDL &vdl ) 04846 { 04847 Statement::exchange_convert( vdl ); 04848 04849 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 04850 04851 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 04852 04853 BinRep *br = new BinRep( new List<BinRep> ); 04854 br->to_tuple().ins_last( new BinRep( "st" )); 04855 br->to_tuple().ins_last( new BinRep( "STOP" )); 04856 S.ins( br ); 04857 04858 if (expr_valid()) { 04859 br = new BinRep( new List<BinRep> ); 04860 br->to_tuple().ins_last( new BinRep( "expr" )); 04861 br->to_tuple().ins_last( 04862 new BinRep( this->expr_guarded().exchange_expr(vdl) )); 04863 S.ins( br ); 04864 } 04865 } 04866 04867 04868 void 04869 StopStmt::convert(BinRep & stmt, ExprTable & etable, 04870 Symtab & NOTUSED(symtab), 04871 const NamelistDict & NOTUSED(namelists), 04872 const FormatDB & NOTUSED(formats), 04873 Dictionary<NextEntry> *next_table) 04874 { 04875 empty_overflow(); 04876 04877 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 04878 List<BinRep> & t = iter.current().to_tuple(); 04879 BinRep & second = t[1]; /// ... The second argument of tuple pairs 04880 String field; 04881 04882 t[0].to_string( field ); 04883 04884 if (!check_common_fields(field, second, etable, 04885 next_table, "StopStmt")) { 04886 if (field == "expr") 04887 _exprlist.modify(STOP_EXPR, 04888 convert_expr(second, etable, "StopStmt")); 04889 else if ((field != "prev") && (field != "st")) 04890 make_overflow(iter, "StopStmt"); 04891 } 04892 } 04893 } 04894 04895 RefSet<Statement> * 04896 StopStmt::build_succ(const StmtList & stmts) const 04897 { 04898 RefSet<Statement> *new_succ = new RefSet<Statement>; 04899 04900 Statement * fes = stmts._last_ref(); 04901 04902 if (fes && fes->stmt_class() == FLOW_EXIT_STMT) 04903 new_succ->ins( *fes ); 04904 04905 return new_succ; 04906 } 04907 04908 04909 04910 void 04911 PauseStmt::expr(Expression * e) 04912 { 04913 _exprlist.modify(PAUSE_EXPR, e); 04914 } 04915 04916 PauseStmt::PauseStmt(const char *l) 04917 : Statement(l, PAUSE_STMT) 04918 { 04919 _exprlist.make_static_list(1); 04920 _exprlist.modify(PAUSE_EXPR, omega()); 04921 } 04922 04923 PauseStmt::PauseStmt(const char *l, Expression * expr_exp) 04924 : Statement(l, PAUSE_STMT) 04925 { 04926 _exprlist.make_static_list(1); 04927 _exprlist.modify(PAUSE_EXPR, null_to_omega(expr_exp)); 04928 } 04929 04930 PauseStmt::PauseStmt(const PauseStmt & stmt) 04931 : Statement(stmt.tag(), PAUSE_STMT) 04932 { 04933 copy_base(stmt); 04934 if (stmt._exprlist.valid(PAUSE_EXPR)) 04935 _exprlist.modify(PAUSE_EXPR, stmt._exprlist[PAUSE_EXPR].clone() ); 04936 } 04937 04938 PauseStmt & 04939 PauseStmt::operator = (const PauseStmt & stmt) 04940 { 04941 copy_base(stmt); 04942 04943 if (stmt._exprlist.valid(PAUSE_EXPR)) 04944 _exprlist.modify(PAUSE_EXPR, stmt._exprlist[PAUSE_EXPR].clone() ); 04945 else 04946 _exprlist.modify(PAUSE_EXPR, NULL); 04947 04948 return *this; 04949 } 04950 04951 04952 Statement * 04953 PauseStmt::clone() const 04954 { 04955 return new PauseStmt(*this); 04956 } 04957 04958 PauseStmt::~PauseStmt() 04959 { 04960 /// ... nothing to do 04961 } 04962 04963 void 04964 PauseStmt::fortran_write(ostream & o, 04965 int & indent, 04966 char * NOTUSED(type)) const 04967 { 04968 fortran_indent( o, indent ); 04969 04970 o << "PAUSE "; 04971 if (_exprlist.valid(PAUSE_EXPR)) 04972 o << _exprlist[PAUSE_EXPR]; 04973 } 04974 04975 void 04976 PauseStmt::print_debug(ostream & o, int debug) const 04977 { 04978 if (debug) 04979 o << " {"; /// ... comment '}' 04980 else { 04981 o << "PAUSE "; 04982 if (_exprlist.valid(PAUSE_EXPR)) 04983 o << _exprlist[PAUSE_EXPR]; 04984 } 04985 } 04986 04987 int 04988 PauseStmt::structures_OK() const 04989 { 04990 int OK = Statement::in_out_refs_structures_OK(); 04991 04992 return OK; 04993 } 04994 04995 void 04996 PauseStmt::exchange_convert( VDL &vdl ) 04997 { 04998 Statement::exchange_convert( vdl ); 04999 05000 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 05001 05002 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 05003 05004 BinRep *br = new BinRep( new List<BinRep> ); 05005 br->to_tuple().ins_last( new BinRep( "st" )); 05006 br->to_tuple().ins_last( new BinRep( "PAUSE" )); 05007 S.ins( br ); 05008 05009 if (expr_valid()) { 05010 br = new BinRep( new List<BinRep> ); 05011 br->to_tuple().ins_last( new BinRep( "expr" )); 05012 br->to_tuple().ins_last( 05013 new BinRep( this->expr_guarded().exchange_expr(vdl) )); 05014 S.ins( br ); 05015 } 05016 } 05017 05018 05019 void 05020 PauseStmt::convert(BinRep & stmt, ExprTable & etable, 05021 Symtab & NOTUSED(symtab), 05022 const NamelistDict & NOTUSED(namelists), 05023 const FormatDB & NOTUSED(formats), 05024 Dictionary<NextEntry> *next_table) 05025 { 05026 empty_overflow(); 05027 05028 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 05029 List<BinRep> & t = iter.current().to_tuple(); 05030 BinRep & second = t[1]; /// ... The second argument of tuple pairs 05031 String field; 05032 05033 t[0].to_string( field ); 05034 05035 if (!check_common_fields(field, second, etable, 05036 next_table, "PauseStmt")) { 05037 if (field == "expr") 05038 _exprlist.modify(PAUSE_EXPR, 05039 convert_expr(second, etable, "StopStmt")); 05040 else if ((field != "prev") && (field != "st")) 05041 make_overflow(iter, "PauseStmt"); 05042 } 05043 } 05044 } 05045 05046 05047 05048 FlowEntryStmt::FlowEntryStmt(const char *l) 05049 : Statement(l, FLOW_ENTRY_STMT) 05050 { 05051 /// ... nothing to do 05052 } 05053 05054 FlowEntryStmt::FlowEntryStmt(const FlowEntryStmt & stmt) 05055 : Statement(stmt.tag(), FLOW_ENTRY_STMT) 05056 { 05057 copy_base(stmt); 05058 } 05059 05060 FlowEntryStmt & 05061 FlowEntryStmt::operator = (const FlowEntryStmt & stmt) 05062 { 05063 copy_base(stmt); 05064 return *this; 05065 } 05066 05067 Statement * 05068 FlowEntryStmt::clone() const 05069 { 05070 return new FlowEntryStmt(*this); 05071 } 05072 05073 FlowEntryStmt::~FlowEntryStmt() 05074 { 05075 /// ... nothing to do 05076 } 05077 05078 void 05079 FlowEntryStmt::fortran_write(ostream & NOTUSED(o), 05080 int & NOTUSED(indent), 05081 char * NOTUSED(type)) const 05082 { 05083 /// ... nothing to do 05084 } 05085 05086 void 05087 FlowEntryStmt::print_debug(ostream & o, int debug) const 05088 { 05089 if (!debug) 05090 o << "FLOWENTRY"; 05091 else 05092 o << " {"; /// ... comment '}' 05093 } 05094 05095 int 05096 FlowEntryStmt::structures_OK() const 05097 { 05098 int OK = Statement::in_out_refs_structures_OK(); 05099 05100 return OK; 05101 } 05102 05103 void 05104 FlowEntryStmt::exchange_convert( VDL &vdl ) 05105 { 05106 Statement::exchange_convert( vdl ); 05107 05108 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 05109 05110 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 05111 05112 BinRep *br = new BinRep( new List<BinRep> ); 05113 br->to_tuple().ins_last( new BinRep( "st" )); 05114 br->to_tuple().ins_last( new BinRep( "FLOW_ENTRY" )); 05115 S.ins( br ); 05116 } 05117 05118 05119 void 05120 FlowEntryStmt::convert(BinRep & stmt, ExprTable & etable, 05121 Symtab & NOTUSED(symtab), 05122 const NamelistDict & NOTUSED(namelists), 05123 const FormatDB & NOTUSED(formats), 05124 Dictionary<NextEntry> *next_table) 05125 { 05126 empty_overflow(); 05127 05128 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 05129 List<BinRep> & t = iter.current().to_tuple(); 05130 BinRep & second = t[1]; /// ... The second argument of tuple pairs 05131 String field; 05132 05133 t[0].to_string( field ); 05134 05135 if (!check_common_fields(field, second, etable, 05136 next_table, "FlowEntryStmt")) { 05137 if ((field != "prev") && (field != "st") && (field != "follow")) 05138 make_overflow(iter, "FlowEntryStmt"); 05139 } 05140 } 05141 } 05142 05143 RefSet<Statement> * 05144 FlowEntryStmt::build_succ(const StmtList &stmts) const 05145 { 05146 RefSet<Statement> *new_succ = new RefSet<Statement>; 05147 05148 Iterator<Statement> iter = stmts.iterate_entry_points(); 05149 05150 for( ; iter.valid(); ++iter) { 05151 if (iter.current().stmt_class() == ENTRY_STMT) 05152 new_succ->ins( iter.current() ); 05153 } 05154 05155 if (next_ref() != 0) 05156 new_succ->ins(*next_ref()); 05157 05158 return new_succ; 05159 } 05160 05161 05162 05163 FlowExitStmt::FlowExitStmt(const char *l) 05164 : Statement(l, FLOW_EXIT_STMT) 05165 { 05166 /// ... nothing to do 05167 } 05168 05169 FlowExitStmt::FlowExitStmt(const FlowExitStmt & stmt) 05170 : Statement(stmt.tag(), FLOW_EXIT_STMT) 05171 { 05172 copy_base(stmt); 05173 } 05174 05175 FlowExitStmt & 05176 FlowExitStmt::operator = (const FlowExitStmt & stmt) 05177 { 05178 copy_base(stmt); 05179 return *this; 05180 } 05181 05182 Statement * 05183 FlowExitStmt::clone() const 05184 { 05185 return new FlowExitStmt(*this); 05186 } 05187 05188 FlowExitStmt::~FlowExitStmt() 05189 { 05190 /// ... nothing to do 05191 } 05192 05193 void 05194 FlowExitStmt::fortran_write(ostream & NOTUSED(o), 05195 int & NOTUSED(indent), 05196 char * NOTUSED(type)) const 05197 { 05198 /// ... nothing to do 05199 } 05200 05201 void 05202 FlowExitStmt::print_debug(ostream & o, int debug) const 05203 { 05204 if (!debug) 05205 o << "FLOWEXIT"; 05206 else 05207 o << " {"; /// ... comment '}' 05208 } 05209 05210 int 05211 FlowExitStmt::structures_OK() const 05212 { 05213 int OK = Statement::in_out_refs_structures_OK(); 05214 05215 return OK; 05216 } 05217 05218 void 05219 FlowExitStmt::exchange_convert( VDL &vdl ) 05220 { 05221 Statement::exchange_convert( vdl ); 05222 05223 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 05224 05225 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 05226 05227 BinRep *br = new BinRep( new List<BinRep> ); 05228 br->to_tuple().ins_last( new BinRep( "st" )); 05229 br->to_tuple().ins_last( new BinRep( "FLOW_EXIT" )); 05230 S.ins( br ); 05231 } 05232 05233 05234 void 05235 FlowExitStmt::convert(BinRep & stmt, ExprTable & etable, 05236 Symtab & NOTUSED(symtab), 05237 const NamelistDict & NOTUSED(namelists), 05238 const FormatDB & NOTUSED(formats), 05239 Dictionary<NextEntry> *next_table) 05240 { 05241 empty_overflow(); 05242 05243 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 05244 List<BinRep> & t = iter.current().to_tuple(); 05245 BinRep & second = t[1]; /// ... The second argument of tuple pairs 05246 String field; 05247 05248 t[0].to_string( field ); 05249 05250 if (!check_common_fields(field, second, etable, 05251 next_table, "FlowExitStmt")) { 05252 if ((field != "prev") && (field != "st")) 05253 make_overflow(iter, "FlowExitStmt"); 05254 } 05255 } 05256 } 05257 05258 RefSet<Statement> * 05259 FlowExitStmt::build_succ(const StmtList & NOTUSED(stmts) ) const 05260 { 05261 RefSet<Statement> *new_succ = new RefSet<Statement>; 05262 05263 return new_succ; 05264 } 05265 05266 05267 05268 05269 void 05270 CallStmt::relink_sptrs( ProgramUnit & NOTUSED(p) ) 05271 { 05272 #if 0 05273 _routine = p.symtab().find_ref(_routine->name_ref()); 05274 #endif 05275 } 05276 05277 05278 void 05279 CallStmt::build_refs() 05280 { 05281 /// ... Scoot through the call arguments to calc in_refs and _act_refs 05282 05283 _in_refs.clear(); 05284 _act_refs.clear(); 05285 05286 if (parameters_valid()) { 05287 _add_act_params (parameters_guarded()); 05288 for (Iterator<Expression> iter = parameters_guarded().arg_list(); 05289 iter.valid(); ++iter) { 05290 _add_in_refs(iter.current()); 05291 } 05292 } 05293 05294 /// ... _out_refs are the same as the act_refs 05295 05296 _out_refs = _act_refs; 05297 05298 } 05299 05300 int 05301 CallStmt::iterate_in_exprs_valid() const 05302 { 05303 return routine_valid(); 05304 } 05305 05306 Mutator<Expression> 05307 CallStmt::iterate_in_exprs_guarded() 05308 { 05309 /// input expr is routine 05310 return Mutator<Expression>(_exprlist, 05311 &_exprlist[ROUTINE_EXPR], 05312 &_exprlist[ROUTINE_EXPR]); 05313 } 05314 05315 int 05316 CallStmt::iterate_in_out_exprs_valid() const 05317 { 05318 return parameters_valid(); 05319 } 05320 05321 Mutator<Expression> 05322 CallStmt::iterate_in_out_exprs_guarded() 05323 { 05324 /// in-out exprs are those on parameter list 05325 return Mutator<Expression>(parameters_guarded().arg_list()); 05326 } 05327 05328 void 05329 CallStmt::parameters(Expression *e) 05330 { 05331 p_assert(e->op() == COMMA_OP, 05332 "CallStmt::parameters(Expression *): CommaExpr expected"); 05333 05334 _exprlist.modify(PARAMETERS, e); 05335 build_refs(); 05336 } 05337 05338 void 05339 CallStmt::routine(Expression *e) 05340 { 05341 p_assert(e->op() == ID_OP, 05342 "CallStmt::routine(Expression *): IdExpr expected"); 05343 05344 _exprlist.modify(ROUTINE_EXPR, e); 05345 build_refs(); 05346 } 05347 05348 CallStmt::CallStmt(const char *l) 05349 : Statement(l, CALL_STMT) 05350 { 05351 _exprlist.make_static_list(2); 05352 _exprlist.modify(ROUTINE_EXPR, omega()); 05353 _exprlist.modify(PARAMETERS, omega()); 05354 } 05355 05356 CallStmt::CallStmt(const char *l, 05357 Expression *routine_exp, 05358 Expression *parameters_exp) 05359 : Statement(l, CALL_STMT) 05360 { 05361 p_assert(routine_exp->op() == ID_OP, 05362 "CallStmt( ): 'routine' must be a IdExpr"); 05363 05364 p_assert(parameters_exp->op() == COMMA_OP, 05365 "CallStmt( ): 'parameters' must be a CommaExpr"); 05366 05367 _exprlist.make_static_list(2); 05368 05369 _exprlist.modify(ROUTINE_EXPR, null_to_omega(routine_exp)); 05370 _exprlist.modify(PARAMETERS, null_to_omega(parameters_exp)); 05371 05372 build_refs(); 05373 } 05374 05375 CallStmt::CallStmt(const CallStmt & stmt) 05376 : Statement(stmt.tag(), CALL_STMT) 05377 { 05378 copy_base(stmt); 05379 05380 if (stmt._exprlist.valid(ROUTINE_EXPR)) 05381 _exprlist.modify(ROUTINE_EXPR, stmt._exprlist[ROUTINE_EXPR].clone() ); 05382 else 05383 _exprlist.modify(ROUTINE_EXPR, NULL); 05384 05385 if (stmt._exprlist.valid(PARAMETERS)) 05386 _exprlist.modify(PARAMETERS, stmt._exprlist[PARAMETERS].clone() ); 05387 else 05388 _exprlist.modify(PARAMETERS, NULL); 05389 05390 build_refs(); 05391 } 05392 05393 CallStmt & 05394 CallStmt::operator = (const CallStmt & stmt) 05395 { 05396 copy_base(stmt); 05397 05398 if (stmt._exprlist.valid(ROUTINE_EXPR)) 05399 _exprlist.modify(ROUTINE_EXPR, stmt._exprlist[ROUTINE_EXPR].clone() ); 05400 else 05401 _exprlist.modify(ROUTINE_EXPR, NULL); 05402 05403 if (stmt._exprlist.valid(PARAMETERS)) 05404 _exprlist.modify(PARAMETERS, stmt._exprlist[PARAMETERS].clone() ); 05405 else 05406 _exprlist.modify(PARAMETERS, NULL); 05407 05408 build_refs(); 05409 return *this; 05410 } 05411 05412 Statement * 05413 CallStmt::clone() const 05414 { 05415 return new CallStmt(*this); 05416 } 05417 05418 CallStmt::~CallStmt() 05419 { 05420 /// ... nothing to do 05421 } 05422 05423 void 05424 CallStmt::fortran_write(ostream & o, 05425 int & indent, 05426 char * NOTUSED(type)) const 05427 { 05428 fortran_indent( o, indent ); 05429 05430 o << "CALL "; 05431 05432 if (_exprlist.valid(ROUTINE_EXPR)) 05433 o << _exprlist[ROUTINE_EXPR]; 05434 else 05435 o << "<INVALID>"; 05436 05437 if (_exprlist.valid(PARAMETERS)) 05438 o << "(" << _exprlist[PARAMETERS] << ")"; 05439 } 05440 05441 void 05442 CallStmt::print_debug(ostream & o, int debug) const 05443 { 05444 if (debug) 05445 o << " {"; /// ... comment '}' 05446 else { 05447 o << "CALL "; 05448 05449 if (_exprlist.valid(ROUTINE_EXPR)) 05450 o << _exprlist[ROUTINE_EXPR]; 05451 else 05452 o << "<INVALID>"; 05453 05454 if (_exprlist.valid(PARAMETERS)) 05455 o << "(" << _exprlist[PARAMETERS] << ")"; 05456 } 05457 } 05458 05459 int 05460 CallStmt::structures_OK() const 05461 { 05462 int OK = Statement::in_out_refs_structures_OK(); 05463 05464 return OK; 05465 } 05466 05467 void 05468 CallStmt::exchange_convert( VDL &vdl ) 05469 { 05470 Statement::exchange_convert( vdl ); 05471 05472 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 05473 05474 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 05475 05476 BinRep *br = new BinRep( new List<BinRep> ); 05477 br->to_tuple().ins_last( new BinRep( "st" )); 05478 br->to_tuple().ins_last( new BinRep( "CALL" )); 05479 S.ins( br ); 05480 05481 if (parameters_valid()) { 05482 br = new BinRep( new List<BinRep> ); 05483 br->to_tuple().ins_last( new BinRep( "parameters" )); 05484 br->to_tuple().ins_last( 05485 new BinRep( this->parameters_guarded().exchange_expr(vdl) )); 05486 S.ins( br ); 05487 } 05488 } 05489 05490 05491 void 05492 CallStmt::convert(BinRep & stmt, ExprTable & etable, Symtab & symtab, 05493 const NamelistDict & NOTUSED(namelists), 05494 const FormatDB & NOTUSED(formats), 05495 Dictionary<NextEntry> *next_table) 05496 { 05497 empty_overflow(); 05498 05499 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 05500 List<BinRep> & t = iter.current().to_tuple(); 05501 BinRep & second = t[1]; /// ... The second argument of tuple pairs 05502 String field; 05503 05504 t[0].to_string( field ); 05505 05506 if (!check_common_fields(field, second, etable, 05507 next_table, "CallStmt")) { 05508 if (field == "routine") { 05509 String second_str; 05510 second.to_string(second_str); 05511 _exprlist.modify(ROUTINE_EXPR, 05512 id(*symtab.find_ref(second_str))); 05513 } 05514 else if (field == "parameters") 05515 _exprlist.modify(PARAMETERS, 05516 convert_expr(second, etable, "CallStmt")); 05517 else if ((field != "prev") && (field != "st")) 05518 make_overflow(iter, "CallStmt"); 05519 } 05520 } 05521 } 05522 05523 RefSet<Statement> * 05524 CallStmt::build_succ(const StmtList & NOTUSED(stmts)) const 05525 { 05526 RefSet<Statement> *new_succ = new RefSet<Statement>; 05527 05528 new_succ->ins(*next_ref()); 05529 05530 return new_succ; 05531 } 05532 05533 05534 void 05535 EntryStmt::relink_sptrs( ProgramUnit & NOTUSED(p) ) 05536 { 05537 #if 0 05538 _routine = p.symtab().find_ref(_routine->name_ref()); 05539 #endif 05540 } 05541 05542 Boolean 05543 EntryStmt::access_summary_exists() 05544 { 05545 if (_access_summary) { 05546 return True; 05547 } else { 05548 return False; 05549 } 05550 } 05551 05552 SymbolAccessRefMap & 05553 EntryStmt::access_summary( ) 05554 { 05555 return (SymbolAccessRefMap &) *_access_summary; 05556 } 05557 05558 void 05559 EntryStmt::write_access_summary( ostream & o) 05560 { 05561 if (_access_table) { 05562 _access_table->write( o, *this ); 05563 } else if (_access_summary) { 05564 _access_summary->write( o, *this ); 05565 } 05566 } 05567 05568 void 05569 EntryStmt::access_summary( SymbolAccessRefMap * sarm ) 05570 { 05571 if (_access_summary) { 05572 delete _access_summary; 05573 } 05574 _access_summary = sarm; 05575 } 05576 05577 void 05578 EntryStmt::parameters(Expression * e) 05579 { 05580 p_assert(e->op() == COMMA_OP, 05581 "EntryStmt::parameters(Expression *): CommaExpr expected"); 05582 05583 _exprlist.modify(PARAMETERS, e); 05584 } 05585 05586 void 05587 EntryStmt::routine(Expression *e) 05588 { 05589 p_assert(e->op() == ID_OP, 05590 "EntryStmt::routine(Expression *): IdExpr expected"); 05591 05592 _exprlist.modify(ROUTINE_EXPR, e); 05593 } 05594 05595 05596 EntryStmt::EntryStmt(const char *l) 05597 : Statement(l, ENTRY_STMT) 05598 { 05599 _access_summary = 0; 05600 05601 _exprlist.make_static_list(2); 05602 _exprlist.modify(ROUTINE_EXPR, omega()); 05603 _exprlist.modify(PARAMETERS, omega()); 05604 } 05605 05606 EntryStmt::EntryStmt(const char *l, 05607 Expression *routine_exp, 05608 Expression *parameters_exp) 05609 : Statement(l, ENTRY_STMT) 05610 { 05611 p_assert(routine_exp && routine_exp->op() == ID_OP, 05612 "EntryStmt( ): 'routine' must be a IdExpr"); 05613 05614 p_assert(parameters_exp && parameters_exp->op() == COMMA_OP, 05615 "EntryStmt( ): 'parameters' must be a CommaExpr"); 05616 05617 _access_summary = 0; 05618 05619 _exprlist.make_static_list(2); 05620 05621 _exprlist.modify(ROUTINE_EXPR, null_to_omega(routine_exp)); 05622 _exprlist.modify(PARAMETERS, null_to_omega(parameters_exp)); 05623 } 05624 05625 EntryStmt::EntryStmt(const char *l, 05626 Expression *routine_exp, 05627 Expression *parameters_exp, 05628 SymbolAccessRefMap * refmap) 05629 : Statement(l, ENTRY_STMT) 05630 { 05631 p_assert(routine_exp && routine_exp->op() == ID_OP, 05632 "EntryStmt( ): 'routine' must be a IdExpr"); 05633 05634 p_assert(parameters_exp && parameters_exp->op() == COMMA_OP, 05635 "EntryStmt( ): 'parameters' must be a CommaExpr"); 05636 05637 _access_summary = refmap; 05638 05639 _exprlist.make_static_list(2); 05640 05641 _exprlist.modify(ROUTINE_EXPR, null_to_omega(routine_exp)); 05642 _exprlist.modify(PARAMETERS, null_to_omega(parameters_exp)); 05643 } 05644 05645 EntryStmt::EntryStmt(const EntryStmt & stmt) 05646 : Statement(stmt.tag(), ENTRY_STMT) 05647 { 05648 copy_base(stmt); 05649 05650 if (stmt._access_summary) { 05651 05652 _access_summary = new SymbolAccessRefMap(); 05653 _access_summary->incorporate(*stmt._access_summary); 05654 } else { 05655 _access_summary = 0; 05656 } 05657 05658 if (stmt._exprlist.valid(ROUTINE_EXPR)) 05659 _exprlist.modify(ROUTINE_EXPR, stmt._exprlist[ROUTINE_EXPR].clone() ); 05660 05661 if (stmt._exprlist.valid(PARAMETERS)) 05662 _exprlist.modify(PARAMETERS, stmt._exprlist[PARAMETERS].clone() ); 05663 } 05664 05665 EntryStmt & 05666 EntryStmt::operator = (const EntryStmt & stmt) 05667 { 05668 copy_base(stmt); 05669 05670 if (stmt._access_summary) { 05671 05672 _access_summary = new SymbolAccessRefMap(); 05673 _access_summary->incorporate(*stmt._access_summary); 05674 } 05675 05676 if (stmt._exprlist.valid(ROUTINE_EXPR)) 05677 _exprlist.modify(ROUTINE_EXPR, stmt._exprlist[ROUTINE_EXPR].clone() ); 05678 else 05679 _exprlist.modify(ROUTINE_EXPR, NULL); 05680 05681 if (stmt._exprlist.valid(PARAMETERS)) 05682 _exprlist.modify(PARAMETERS, stmt._exprlist[PARAMETERS].clone() ); 05683 else 05684 _exprlist.modify(PARAMETERS, NULL); 05685 05686 return *this; 05687 } 05688 05689 Statement * 05690 EntryStmt::clone() const 05691 { 05692 return new EntryStmt(*this); 05693 } 05694 05695 EntryStmt::~EntryStmt() 05696 { 05697 if (_access_summary) { 05698 delete _access_summary; 05699 } 05700 } 05701 05702 void 05703 EntryStmt::fortran_write(ostream & o, 05704 int & indent, 05705 char * type) const 05706 { 05707 fortran_indent( o, indent ); 05708 05709 if (type == "") { 05710 o << "ENTRY "; 05711 } 05712 else { 05713 o << type << " "; /// ... Main entry point of program unit 05714 } 05715 05716 if (_exprlist.valid(ROUTINE_EXPR)) 05717 o << _exprlist[ROUTINE_EXPR]; 05718 05719 if (_exprlist.valid(PARAMETERS)) { 05720 const Expression &e = _exprlist[PARAMETERS]; 05721 if (e.op() == COMMA_OP && e.arg_list().entries() > 0) { 05722 o << "(" << _exprlist[PARAMETERS] << ")"; 05723 } else { 05724 if (routine_guarded().op()==ID_OP){ 05725 switch(routine_guarded().symbol().sym_class()){ 05726 case FUNCTION_CLASS: 05727 /// ... silvius: f77 on Linux complains about functions like this: 05728 /// ... FUNCTION f 05729 /// ... It needs: 05730 /// ... FUNCTION f() 05731 o << "(" << ")"; 05732 } 05733 } 05734 } 05735 } else { 05736 if (routine_guarded().op()==ID_OP){ 05737 switch(routine_guarded().symbol().sym_class()){ 05738 case FUNCTION_CLASS: 05739 // silvius: f77 on Linux complains about functions like this: 05740 // FUNCTION f 05741 // It needs: 05742 // FUNCTION f() 05743 o << "(" << ")"; 05744 } 05745 } 05746 } 05747 } 05748 05749 void 05750 EntryStmt::print_debug(ostream & o, int debug) const 05751 { 05752 if (!debug) { 05753 o << "ENTRY "; 05754 05755 if (_exprlist.valid(ROUTINE_EXPR)) 05756 o << _exprlist[ROUTINE_EXPR]; 05757 05758 if (_exprlist.valid(PARAMETERS)) 05759 o << "(" << _exprlist[PARAMETERS] << ")"; 05760 05761 if (_access_summary) { 05762 o << " _access_summary={" << *_access_summary << "}"; 05763 } 05764 } 05765 else { 05766 o << " {"; /// ... comment '}' 05767 } 05768 } 05769 05770 int 05771 EntryStmt::structures_OK() const 05772 { 05773 int OK = Statement::in_out_refs_structures_OK(); 05774 05775 return OK; 05776 } 05777 05778 void 05779 EntryStmt::exchange_convert( VDL &vdl ) 05780 { 05781 Statement::exchange_convert( vdl ); 05782 05783 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 05784 05785 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 05786 05787 BinRep *br = new BinRep( new List<BinRep> ); 05788 br->to_tuple().ins_last( new BinRep( "st" )); 05789 br->to_tuple().ins_last( new BinRep( "ENTRY" )); 05790 S.ins( br ); 05791 05792 if (parameters_valid()) { 05793 br = new BinRep( new List<BinRep> ); 05794 br->to_tuple().ins_last( new BinRep( "parameters" )); 05795 br->to_tuple().ins_last( 05796 new BinRep( this->parameters_guarded().exchange_expr(vdl) )); 05797 S.ins( br ); 05798 } 05799 } 05800 05801 05802 void 05803 EntryStmt::convert(BinRep & stmt, ExprTable & etable, 05804 Symtab & symtab, 05805 const NamelistDict & NOTUSED(namelists), 05806 const FormatDB & NOTUSED(formats), 05807 Dictionary<NextEntry> *next_table) 05808 { 05809 empty_overflow(); 05810 05811 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 05812 List<BinRep> & t = iter.current().to_tuple(); 05813 BinRep & second = t[1]; /// ... The second argument of tuple pairs 05814 String field; 05815 05816 t[0].to_string( field ); 05817 05818 if (!check_common_fields(field, second, etable, 05819 next_table, "EntryStmt")) { 05820 if (field == "routine") { 05821 String second_str; 05822 second.to_string(second_str); 05823 _exprlist.modify(ROUTINE_EXPR, 05824 id(*symtab.find_ref(second_str))); 05825 } 05826 else if (field == "parameters") 05827 _exprlist.modify(PARAMETERS, 05828 convert_expr(second, etable, "EntryStmt")); 05829 else if ((field != "prev") && (field != "st")) 05830 make_overflow(iter, "EntryStmt"); 05831 } 05832 } 05833 } 05834 05835 05836 05837 void 05838 ReturnStmt::build_refs() 05839 { 05840 05841 _in_refs.clear(); 05842 _act_refs.clear(); 05843 05844 if (expr_valid()) { 05845 _add_in_refs(expr_guarded()); 05846 _add_act_refs(expr_guarded()); 05847 } 05848 05849 /// ... _out_refs are the same as the act_refs 05850 05851 _out_refs = _act_refs; 05852 05853 } 05854 05855 void 05856 ReturnStmt::expr(Expression * e) 05857 { 05858 _exprlist.modify(RETURN_EXPR, e); 05859 build_refs(); 05860 } 05861 05862 05863 ReturnStmt::ReturnStmt(const char *l) 05864 : Statement(l, RETURN_STMT) 05865 { 05866 _exprlist.make_static_list(1); 05867 _exprlist.modify(RETURN_EXPR, omega()); 05868 } 05869 05870 ReturnStmt::ReturnStmt(const char *l, Expression * expr_exp) 05871 : Statement(l, RETURN_STMT) 05872 { 05873 _exprlist.make_static_list(1); 05874 _exprlist.modify(RETURN_EXPR, null_to_omega(expr_exp)); 05875 05876 build_refs(); 05877 } 05878 05879 ReturnStmt::ReturnStmt(const ReturnStmt & stmt) 05880 : Statement(stmt.tag(), RETURN_STMT) 05881 { 05882 copy_base(stmt); 05883 build_refs(); 05884 } 05885 05886 ReturnStmt & 05887 ReturnStmt::operator = (const ReturnStmt & stmt) 05888 { 05889 copy_base(stmt); 05890 _exprlist.modify(RETURN_EXPR, NULL); 05891 build_refs(); 05892 return *this; 05893 } 05894 05895 05896 Statement * 05897 ReturnStmt::clone() const 05898 { 05899 return new ReturnStmt(*this); 05900 } 05901 05902 ReturnStmt::~ReturnStmt() 05903 { 05904 /// ... nothing to do 05905 } 05906 05907 void 05908 ReturnStmt::fortran_write(ostream & o, 05909 int & indent, 05910 char * NOTUSED(type)) const 05911 { 05912 fortran_indent( o, indent ); 05913 05914 o << "RETURN "; 05915 if (_exprlist.valid(RETURN_EXPR)) 05916 o << _exprlist[RETURN_EXPR]; 05917 } 05918 05919 void 05920 ReturnStmt::print_debug(ostream & o, int debug) const 05921 { 05922 if (!debug) { 05923 o << "RETURN "; 05924 if (_exprlist.valid(RETURN_EXPR)) 05925 o << _exprlist[RETURN_EXPR]; 05926 } 05927 else 05928 o << " {"; /// ... comment '}' 05929 } 05930 05931 int 05932 ReturnStmt::structures_OK() const 05933 { 05934 int OK = Statement::in_out_refs_structures_OK(); 05935 05936 return OK; 05937 } 05938 05939 void 05940 ReturnStmt::exchange_convert( VDL &vdl ) 05941 { 05942 Statement::exchange_convert( vdl ); 05943 05944 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 05945 05946 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 05947 05948 BinRep *br = new BinRep( new List<BinRep> ); 05949 br->to_tuple().ins_last( new BinRep( "st" )); 05950 br->to_tuple().ins_last( new BinRep( "RETURN" )); 05951 S.ins( br ); 05952 05953 } 05954 05955 05956 void 05957 ReturnStmt::convert(BinRep & stmt, ExprTable & etable, 05958 Symtab & NOTUSED(symtab), 05959 const NamelistDict & NOTUSED(namelists), 05960 const FormatDB & NOTUSED(formats), 05961 Dictionary<NextEntry> *next_table) 05962 { 05963 empty_overflow(); 05964 05965 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 05966 List<BinRep> & t = iter.current().to_tuple(); 05967 BinRep & second = t[1]; /// ... The second argument of tuple pairs 05968 String field; 05969 05970 t[0].to_string( field ); 05971 05972 if (!check_common_fields(field, second, etable, 05973 next_table, "ReturnStmt")) { 05974 if (field == "expr") 05975 _exprlist.modify(RETURN_EXPR, 05976 convert_expr(second, etable, "ReturnStmt")); 05977 else if ((field != "prev") && (field != "st")) 05978 make_overflow(iter, "ReturnStmt"); 05979 } 05980 } 05981 } 05982 05983 RefSet<Statement> * 05984 ReturnStmt::build_succ(const StmtList & stmts) const 05985 { 05986 RefSet<Statement> *new_succ = new RefSet<Statement>; 05987 05988 Statement *fes = stmts._last_ref(); 05989 05990 if (fes && fes->stmt_class() == FLOW_EXIT_STMT) 05991 new_succ->ins( *fes ); 05992 05993 return new_succ; 05994 } 05995 05996 05997 05998 05999 LabelStmt::LabelStmt(const char *l) 06000 : Statement(l, LABEL_STMT) 06001 { 06002 /// ... nothing to do 06003 } 06004 06005 LabelStmt::LabelStmt(const char *l, int long_value) 06006 : Statement(l, LABEL_STMT) 06007 { 06008 _value = long_value; 06009 } 06010 06011 LabelStmt::LabelStmt(const LabelStmt & stmt) 06012 : Statement(stmt.tag(), LABEL_STMT) 06013 { 06014 copy_base(stmt); 06015 _value = stmt._value; 06016 } 06017 06018 LabelStmt & 06019 LabelStmt::operator = (const LabelStmt & stmt) 06020 { 06021 copy_base(stmt); 06022 _value = stmt._value; 06023 return *this; 06024 } 06025 06026 Statement * 06027 LabelStmt::clone() const 06028 { 06029 return new LabelStmt(*this); 06030 } 06031 06032 LabelStmt::~LabelStmt() 06033 { 06034 /// ... nothing to do 06035 } 06036 06037 void 06038 LabelStmt::fortran_write(ostream & o, 06039 int & indent, 06040 char * NOTUSED(type)) const 06041 { 06042 fortran_indent( o, indent ); 06043 06044 o << "CONTINUE "; 06045 } 06046 06047 void 06048 LabelStmt::print_debug(ostream & o, int debug) const 06049 { 06050 if (!debug) 06051 o << "LABEL " << _value; 06052 else 06053 o << " {"; /// ... comment '}' 06054 } 06055 06056 int 06057 LabelStmt::structures_OK() const 06058 { 06059 int OK = Statement::in_out_refs_structures_OK(); 06060 06061 return OK; 06062 } 06063 06064 void 06065 LabelStmt::exchange_convert( VDL &vdl ) 06066 { 06067 Statement::exchange_convert( vdl ); 06068 06069 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 06070 06071 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 06072 06073 BinRep *br = new BinRep( new List<BinRep> ); 06074 br->to_tuple().ins_last( new BinRep( "st" )); 06075 br->to_tuple().ins_last( new BinRep( "LABEL" )); 06076 S.ins( br ); 06077 06078 br = new BinRep( new List<BinRep> ); 06079 br->to_tuple().ins_last( new BinRep( "label" )); 06080 br->to_tuple().ins_last( new BinRep( this->value() )); 06081 S.ins( br ); 06082 } 06083 06084 06085 void 06086 LabelStmt::convert(BinRep & stmt, ExprTable & etable, 06087 Symtab & NOTUSED(symtab), 06088 const NamelistDict & NOTUSED(namelists), 06089 const FormatDB & NOTUSED(formats), 06090 Dictionary<NextEntry> *next_table) 06091 { 06092 empty_overflow(); 06093 06094 for (Iterator<BinRep> iter = stmt.to_set(); iter.valid(); ++iter) { 06095 List<BinRep> & t = iter.current().to_tuple(); 06096 BinRep & second = t[1]; /// ... The second argument of tuple pairs 06097 String field; 06098 06099 t[0].to_string( field ); 06100 06101 if (!check_common_fields(field, second, etable, 06102 next_table, "LabelStmt")) { 06103 if (field == "label") 06104 _value = (second.to_integer()); 06105 else if ((field != "prev") && (field != "st")) 06106 make_overflow(iter, "LabelStmt"); 06107 } 06108 } 06109 } 06110 06111 06112 06113 GotoStmt::GotoStmt(const char *l) 06114 : Statement(l, GOTO_STMT) 06115 { 06116 _target = NULL; 06117 } 06118 06119 GotoStmt::GotoStmt(const char *l, Statement * target_stmt) 06120 : Statement(l, GOTO_STMT) 06121 { 06122 p_assert(target_stmt->stmt_class() == LABEL_STMT, 06123 "GotoStmt( ): the target statement must be a LabelStmt"); 06124 06125 _target = target_stmt; 06126 } 06127 06128 GotoStmt::GotoStmt(const GotoStmt & stmt) 06129 : Statement(stmt.tag(), GOTO_STMT) 06130 { 06131 copy_base(stmt); 06132 _target = stmt._target; 06133 } 06134 06135 GotoStmt & 06136 GotoStmt::operator = (const GotoStmt & stmt) 06137 { 06138 copy_base(stmt); 06139 _target = stmt._target; 06140 return *this; 06141 } 06142 06143 void 06144 GotoStmt::target(Statement * s) 06145 { 06146 p_assert(s->stmt_class() == LABEL_STMT, 06147 "GotoStmt::target(Statement *): LabelStmt expected"); 06148 06149 _target = s; 06150 } 06151 06152 Statement * 06153 GotoStmt::clone() const 06154 { 06155 return new GotoStmt(*this); 06156 } 06157 06158 GotoStmt::~GotoStmt() 06159 { 06160 /// ... nothing to do 06161 } 06162 06163 void 06164 GotoStmt::fortran_write(ostream & o, 06165 int & indent, 06166 char * NOTUSED(type)) const 06167 { 06168 fortran_indent( o, indent ); 06169 06170 o << "GOTO "; 06171 if (_target) 06172 o << _target->value(); 06173 else 06174 o << "<UNDEF>"; 06175 } 06176 06177 void 06178 GotoStmt::print_debug(ostream & o, int debug) const 06179 { 06180 if (!debug) { 06181 o << "GOTO "; 06182 if (_target) 06183 o << _target->tag(); 06184 else 06185 o << "<UNDEF>"; 06186 } 06187 else { 06188 o << " {"; /// ... comment '}' 06189 } 06190 } 06191 06192 int 06193 GotoStmt::structures_OK() const 06194 { 06195 int OK = Statement::in_out_refs_structures_OK(); 06196 06197 return OK; 06198 } 06199 06200 void 06201 GotoStmt::exchange_convert( VDL &vdl ) 06202 { 06203 Statement::exchange_convert( vdl ); 06204 06205 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 06206 06207 Set<BinRep> & S = b->find_ref("statements")->find_ref( tag() )->to_set(); 06208 06209 BinRep *br = new BinRep( new List<BinRep> ); 06210 br->to_tuple().ins_last( new BinRep( "st" )); 06211 br->to_tuple().ins_last( new BinRep( "UNCONDITIONAL_GOTO" )); 06212 S.ins( br ); 06213 06214 br = new BinRep( new List<BinRep> ); 06215 br->to_tuple().ins_last( new BinRep( "target" )); 06216 br->to_tuple().ins_last( new BinRep( target_ref()->tag() )); 06217 S. |