Polaris: Statement.cc Source File

Statement.cc

Go 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.