Polaris: Symbol.cc Source File

Symbol.cc

Go to the documentation of this file.
00001 /// File Symbol.cc
00002 ///
00003 #include "../define.h"
00004 
00005 #ifdef POLARIS_GNU_PRAGMAS
00006 #pragma implementation "Symbol.h"
00007 #pragma implementation "BlockDataSymbol.h"
00008 #pragma implementation "FunctionSymbol.h"
00009 #pragma implementation "NamelistSymbol.h"
00010 #pragma implementation "ProgramSymbol.h"
00011 #pragma implementation "SubroutineSymbol.h"
00012 #pragma implementation "SymbolicConstantSymbol.h"
00013 #pragma implementation "VariableSymbol.h"
00014 #pragma implementation "PointerSymbol.h"
00015 #endif
00016 
00017 #include <stdio.h>
00018 #include <stdlib.h>
00019 
00020 #include "Symbol.h"
00021 
00022 #include "BlockDataSymbol.h"
00023 #include "FunctionSymbol.h"
00024 #include "NamelistSymbol.h"
00025 #include "ProgramSymbol.h"
00026 #include "SubroutineSymbol.h"
00027 #include "SymbolicConstantSymbol.h"
00028 #include "VariableSymbol.h"
00029 #include "PointerSymbol.h"
00030 
00031 #include "../BinRep.h"
00032 #include "../Collection/Iterator.h"
00033 #include "../Collection/RefMap.h"
00034 #include "../CommonBlock.h"
00035 #include "../Equivalence.h"
00036 #include "../ExprTable.h"
00037 #include "../Expression/Expression.h"
00038 #include "../Expression/IntConstExpr.h"
00039 #include "../ProgramUnit.h"
00040 #include "../Statement/Statement.h"
00041 #include "../String.h"
00042 #include "../utilities/expression_util.h"
00043 
00044 #include "../debug.h"
00045 #include "../macros.h"
00046 #include "../p-limits.h"
00047 #include "../p-assert.h"
00048 
00049 template class Map<Symbol,List<Expression> >; 
00050 template class Map<Symbol,List<RefList<ProgramUnit> > >; 
00051 template class Map<Symbol,Statement>; 
00052 template class RefMap<Symbol,ProgramUnit>; 
00053 template class TypedBaseMap<Symbol,List<Expression> >; 
00054 template class TypedBaseMap<Symbol,List<RefList<ProgramUnit> > >; 
00055 template class TypedBaseMap<Symbol,ProgramUnit>; 
00056 template class TypedBaseMap<Symbol,Statement>; 
00057 template class TypedBaseRefMap<Symbol,ProgramUnit>; 
00058 template class ProtoMap<Symbol,List<Expression> >; 
00059 template class ProtoMap<Symbol,List<RefList<ProgramUnit> > >; 
00060 template class ProtoMap<Symbol,Statement>; 
00061 template class ProtoRefMap<Symbol,ProgramUnit>; 
00062 template class KeyIterator<Symbol,List<Expression> >; 
00063 template class KeyIterator<Symbol,List<RefList<ProgramUnit> > >; 
00064 template class KeyIterator<Symbol,ProgramUnit>; 
00065 
00066 
00067 #define CHECK_STRUCTURES(class_name, field)         \
00068 {                                                   \
00069 if ( ! (field).structures_OK()) {                   \
00070     cerr << "In context of " << #class_name         \
00071          << ": " #field << ": " << endl;            \
00072     cerr << *this << endl;                          \
00073     return 0;                                       \
00074   }                                                 \
00075 }
00076 
00077 #define CHECK_PTR_STRUCTURES(class_name, field)     \
00078 {                                                   \
00079   if ( (field) && ! (field)->structures_OK()) {     \
00080     cerr << "In context of " << #class_name         \
00081          << ": " #field << ": " << endl;            \
00082     cerr << *this << endl;                          \
00083     return 0;                                       \
00084   }                                                 \
00085 }
00086 
00087 
00088 /// Note:  This function does NOT fill in the data fields properly--
00089 /// it just gives them dummy values for now.
00090 
00091 Symbol         *
00092 make_symbol(const char *name, const BinRep & binstr)
00093 {
00094     BinRep & insp = CASTAWAY(BinRep &) binstr;
00095 
00096     p_assert( insp.is_set(), "not a set");
00097 
00098     /// ...  Find out which kind of Symbol to make -- look at the "class" field
00099     String          class_type;
00100 
00101     insp["class"].to_string(class_type);
00102 
00103     if (class_type == "PROGRAM")
00104         return new ProgramSymbol(name, 0);
00105     else if (class_type == "ROUTINE") {
00106         /// ...  Note:  This could either be a SubroutineSymbol or FunctionSymbol
00107         /// ...  If it has a "type" class, it's a FunctionSymbol, else it's
00108         /// ...  a SubroutineSymbol
00109 
00110         if (insp["type"].is_omega()) {
00111             return new SubroutineSymbol(name, NOT_EXTERNAL,
00112                                         NOT_INTRINSIC, NOT_FORMAL);
00113         }
00114 
00115         return new FunctionSymbol(name, make_type(UNDEFINED_TYPE),
00116                                   NOT_EXTERNAL, NOT_INTRINSIC, NOT_FORMAL);
00117     }
00118     else if (class_type == "VARIABLE") {
00119         return new VariableSymbol(name, make_type(UNDEFINED_TYPE),
00120                                   NOT_FORMAL, NOT_SAVED);
00121     }
00122     else if (class_type == "SYMBOLIC_CONSTANT") {
00123         return new SymbolicConstantSymbol(name, 0);
00124     }
00125     else if (class_type == "BLOCKDATA") {
00126         return new BlockDataSymbol(name);
00127     }
00128     else if (class_type == "NAMELIST") {
00129         return new NamelistSymbol(name);
00130     }
00131     else if (class_type == "UNKNOWN") {
00132         cerr << "KAP/Polaris error: [class, UNKNOWN] assuming VARIABLE" << endl;
00133 
00134         return new VariableSymbol(name, make_type(UNDEFINED_TYPE),
00135                                   NOT_FORMAL, NOT_SAVED);
00136     }
00137 
00138     cerr << "Error: file Symbol.cc: "
00139          << "make_symbol(): Unrecognized symbol class '"
00140          << class_type << "'" << endl;
00141 
00142     p_abort( "(see above message)" );
00143 
00144     return 0;
00145 }
00146 
00147 /// Returns 1 if binstr is the string "T", else 0 if binstr is the string
00148 /// "F", else aborts with an error (printing out error_context as the 
00149 /// context of the error
00150 
00151 int
00152 convert_true_false(const BinRep & insp, const BinRep & error_context)
00153 {
00154     String          true_false;
00155 
00156     if (insp.is_boolean())
00157         return insp.to_boolean();
00158     else {
00159         insp.to_string(true_false);
00160 
00161         if (true_false == "T") 
00162             return 1;
00163         else if (true_false == "F") 
00164             return 0;
00165 
00166         cerr << "Error: Symbol or derivative: "
00167              << "Expected \"T\" or \"F\" but found \""
00168              << true_false << "\" in binstr:" << endl;
00169         cerr << error_context << endl;
00170 
00171         p_abort( "(see above message)" );
00172     }
00173 
00174     return 0;
00175 }
00176 
00177 
00178 /// class Symbol
00179 
00180 static const char *class_name[] = {
00181      "Undefined Class Type", /// ...  UNDEFINED_CLASS
00182      "ProgramSymbol",       /// ...  PROGRAM_CLASS
00183      "FunctionSymbol",      /// ...  FUNCTION_CLASS,
00184      "SubroutineSymbol",    /// ...  SUBROUTINE_CLASS
00185      "VariableSymbol",      /// ...  VARIABLE_CLASS
00186      "SymbolicConstantSymbol",  /// ...  SYMBOLIC_CONSTANT_CLASS
00187      "BlockDataSymbol",     /// ...  BLOCK_DATA_CLASS
00188      "NamelistSymbol",      /// ...  NAMELIST_CLASS
00189 };
00190 
00191 ostream &
00192 operator << (ostream & o, const Symbol & other) 
00193 {
00194     other.print(o);
00195     return o;
00196 }
00197 
00198 int 
00199 Symbol::_get_size(const BinRep & insp, const BinRep & binstr_context) const
00200 {
00201     /// ...  Pull the size out of this binstr insp -- it should already be
00202     /// ...  positioned on the size itself (not the ["size", ...] tuple).
00203     /// ...  If it is too large, cause an error and print a message.
00204     /// ...  The binstr_context is simply the context of the entire binstr so
00205     /// ...  that it may be printed out in case of an error to track down where the
00206     /// ...  offending size was
00207 
00208     if (insp.is_integer()) {
00209         int size = insp.to_integer();
00210 
00211         if (size >= 0 && size <= MAX_SCALAR_SIZE)
00212             return size;
00213     }
00214 
00215     cerr << "Error: Some derived class of Symbol: "
00216          << "Error in \"size\" field or else size was too large "
00217          << "(current maximum scalar expression size is "
00218          << MAX_SCALAR_SIZE << ") in binstr "
00219          << binstr_context << endl;
00220 
00221     p_abort( "(see above message)" );
00222 
00223     return 0;
00224 }
00225 
00226 void
00227 Symbol::_ref_error(const char *func_name) const
00228 {
00229     cerr << "Error: ";
00230 
00231     if (_sym_class<0 || _sym_class>BLOCK_DATA_CLASS) {
00232         cerr << "Some Derived Class of Symbol "
00233              << "(invalid _sym_class value = "
00234              << (int ) _sym_class << "): ";
00235     }
00236     else
00237         cerr << class_name[_sym_class] << ": ";
00238 
00239     cerr << "The '" << func_name << "' method of this class is not valid."
00240          << "  Check the header file for this class to see which "
00241          << "virtual functions defined in Symbol.h are actually valid"
00242          << " for this class.\n";
00243 
00244     p_abort("(see above message)");
00245 }
00246 
00247 Symbol::~Symbol()
00248 {
00249     #ifdef CLASS_INSTANCE_REGISTRY
00250     unregister_instance(SYMBOL, this);
00251     #endif
00252 
00253     if (_overflow)
00254         delete _overflow;
00255 
00256     _overflow = 0;
00257 }
00258 
00259 const Symbol &
00260 Symbol::assoc_variable() const
00261 {
00262     static Symbol *dummy = 0;
00263     p_abort("Symbol::assoc_variable() not over-ridden by subclass");
00264 
00265     /// ...  This return should never happen.
00266     return *dummy;
00267 }
00268 
00269 Symbol &
00270 Symbol::assoc_variable()
00271 {
00272     static Symbol *dummy = 0;
00273     p_abort("Symbol::assoc_variable() not over-ridden by subclass");
00274 
00275     /// ...  This return should never happen.
00276     return *dummy;
00277 }
00278 
00279 const Type &
00280 Symbol::type() const
00281 {
00282     p_abort("Symbol::type() not over-ridden by subclass");
00283 
00284     /// ...  This call should never happen.
00285     Type *undef_type = new Type(make_type(UNDEFINED_TYPE));
00286     return *undef_type;
00287 }
00288 void
00289 Symbol::_dims (ArrayDims * /* dims */)
00290 {
00291     p_abort("Symbol::_dims() not over-ridden by subclass");
00292 }
00293 
00294 int
00295 Symbol::size() const
00296 {
00297     p_abort("Symbol::size() not over-ridden by subclass");
00298     return 0;
00299 }
00300 
00301 Definition     *
00302 Symbol::definition_clone() const
00303 {
00304     return clone();
00305 }
00306 
00307 //------------------------------------------------------------------------ 
00308 
00309 EXTERNAL_BOOL 
00310 Symbol::external() const 
00311 {
00312     return NOT_EXTERNAL;
00313 }
00314 
00315 void 
00316 Symbol::external(EXTERNAL_BOOL NOTUSED(ourbool)) 
00317 {
00318     _ref_error("external(EXTERNAL_BOOL NOTUSED(ourbool))");
00319 }
00320 
00321 INTRINSIC_BOOL 
00322 Symbol::intrinsic() const 
00323 {
00324     return NOT_INTRINSIC;
00325 }
00326 
00327 void 
00328 Symbol::intrinsic(INTRINSIC_BOOL NOTUSED(ourbool)) 
00329 {
00330     _ref_error("intrinsic(INTRINSIC_BOOL NOTUSED(ourbool))");
00331 }
00332 
00333 const Statement *
00334 Symbol::entry_ref() const 
00335 {
00336     return 0;
00337 }
00338 
00339 Statement *
00340 Symbol::entry_ref() 
00341 {
00342     return 0;
00343 }
00344 
00345 void 
00346 Symbol::entry(Statement * NOTUSED(s)) 
00347 {
00348     _ref_error("entry(Statement * NOTUSED(s))");
00349 }
00350 
00351 void 
00352 Symbol::type(const Type & NOTUSED(type)) 
00353 {
00354     _ref_error("type(const Type & NOTUSED(type))");
00355 }
00356 
00357 Equivalence *
00358 Symbol::equivalence_ref() const 
00359 {
00360     return 0;
00361 }
00362 
00363 void 
00364 Symbol::equivalence(Equivalence & NOTUSED(e), int NOTUSED(byte_base)) 
00365 {
00366     _ref_error("equivalence(Equivalence & NOTUSED(e), int NOTUSED(byte_base))");
00367 }
00368 
00369 void 
00370 Symbol::clear_equivalence() 
00371 {
00372     _ref_error("clear_equivalence()");
00373 }
00374 
00375 void   /// ... _
00376 Symbol::shared_expr(Expression *shared)
00377 {
00378     if (shared)
00379     delete shared;
00380     /// ...  Nothing else happens: Any others than VariableSymbol must be private
00381 }
00382 
00383 void   /// ... _
00384 Symbol::set_to_private()
00385 {
00386     /// ...  Nothing happens
00387 }
00388 
00389 Expression * /// ... _
00390 Symbol::shared_expr() const
00391 {
00392     return 0;   /// ...  Any others than VariableSymbol are private by default
00393 }
00394 
00395 const ArrayDims & 
00396 Symbol::dim() const 
00397 {
00398     static ArrayDims *dummy = 0;
00399     _ref_error("ArrayDims & dim() const");
00400     return *dummy;
00401 }
00402 
00403 ArrayDims & 
00404 Symbol::dim()
00405 {
00406     static ArrayDims *dummy = 0;
00407     _ref_error("ArrayDims & dim() const");
00408     return *dummy;
00409 }
00410 
00411 const SharedDims &
00412 Symbol::shared_dim() const
00413 {
00414     static SharedDims *dummy = 0;
00415     _ref_error("SharedDims & shared_dim() const");
00416     return *dummy;
00417 }
00418 
00419 SharedDims &
00420 Symbol::shared_dim()
00421 {
00422     static SharedDims *dummy = 0;
00423     _ref_error("SharedDims & shared_dim() const");
00424     return *dummy;
00425 }
00426 
00427 FORMAL_BOOL 
00428 Symbol::formal() const 
00429 {
00430     return NOT_FORMAL;
00431 }
00432 
00433 void 
00434 Symbol::formal(FORMAL_BOOL NOTUSED(ourbool)) 
00435 {
00436     _ref_error("formal(FORMAL_BOOL NOTUSED(ourbool))");
00437 }
00438 
00439 INITIAL_BOOL 
00440 Symbol::initial_value() const 
00441 {
00442     return NOT_INITIALIZED;
00443 }
00444 
00445 void 
00446 Symbol::initial_value(INITIAL_BOOL NOTUSED(ourbool)) 
00447 {
00448     _ref_error("initial_value(INITIAL_BOOL NOTUSED(ourbool))");
00449 }
00450 
00451 SAVED_BOOL 
00452 Symbol::saved() const 
00453 {
00454     return NOT_SAVED;
00455 }
00456 
00457 void 
00458 Symbol::saved(SAVED_BOOL NOTUSED(ourbool)) 
00459 {
00460     _ref_error("saved(SAVED_BOOL NOTUSED(ourbool))");
00461 }
00462 
00463 GLOBAL_BOOL 
00464 Symbol::global() const 
00465 {
00466     return NOT_GLOBAL;
00467 }
00468 
00469 ALLOC_BOOL 
00470 Symbol::allocatable() const 
00471 {
00472     return NOT_ALLOCATABLE;
00473 }
00474 
00475 void 
00476 Symbol::global(GLOBAL_BOOL NOTUSED(ourbool)) 
00477 {
00478     _ref_error("global(GLOBAL_BOOL NOTUSED(ourbool))");
00479 }
00480 
00481 void 
00482 Symbol::allocatable(ALLOC_BOOL NOTUSED(ourbool)) 
00483 {
00484     _ref_error("allocatable(ALLOC_BOOL NOTUSED(ourbool))");
00485 }
00486 
00487 const CommonBlock *
00488 Symbol::common_ref() const 
00489 {
00490     return 0;
00491 }
00492 
00493 CommonBlock *
00494 Symbol::common_ref() 
00495 {
00496     return 0;
00497 }
00498 
00499 void 
00500 Symbol::common(CommonBlock & NOTUSED(cb), int NOTUSED(index)) 
00501 {
00502     _ref_error("common(CommonBlock & NOTUSED(cb), int NOTUSED(index))");
00503 }
00504 
00505 void 
00506 Symbol::clear_common() 
00507 {
00508     _ref_error("clear_common()");
00509 }
00510 
00511 const Expression *
00512 Symbol::expr_ref() const 
00513 {
00514     return 0;
00515 }
00516 
00517 Expression *
00518 Symbol::expr_ref() 
00519 {
00520     return 0;
00521 }
00522 
00523 void 
00524 Symbol::expr(Expression * NOTUSED(e)) 
00525 {
00526     _ref_error("expr(Expression * NOTUSED(e))");
00527 }
00528 
00529 int 
00530 Symbol::is_entry() 
00531 {
00532     return False;
00533 }
00534 
00535 int
00536 Symbol::is_scalar() const
00537 {
00538     return False;
00539 }
00540 
00541 int 
00542 Symbol::is_array() const 
00543 {
00544     return False;
00545 }
00546 
00547 int
00548 Symbol::is_shared() const
00549 {
00550     return False;
00551 }
00552 
00553 
00554 //------------------------------------------------------------------------ 
00555 
00556 int
00557 Symbol::structures_OK() const
00558 {
00559     CHECK_STRUCTURES(Symbol, _tag);
00560     CHECK_PTR_STRUCTURES(Symbol, _overflow);
00561 
00562     return 1;
00563 }
00564 
00565 void
00566 Symbol::exchange_convert( VDL &vdl )
00567 {
00568     BinRep *b = CASTAWAY(BinRep *) vdl.data_ref();
00569 
00570     Set<BinRep> & S = b->find_ref("symtab")->to_set();
00571 
00572     BinRep *br = new BinRep( new List<BinRep> );
00573     BinRep *bs = new BinRep( name_ref() );
00574     BinRep *bt = new BinRep( new Set<BinRep> );
00575 
00576     br->to_tuple().ins_last( bs );
00577     br->to_tuple().ins_last( bt );
00578 
00579     S.ins( br );
00580 
00581     Set<BinRep> & T = b->find_ref("symtab")->find_ref( name_ref() )->to_set();
00582 
00583     if (entry_ref() != 0) {
00584         br = new BinRep(new List<BinRep>);
00585         br->to_tuple().ins_last(new BinRep( "entry" ));
00586         br->to_tuple().ins_last(new BinRep( entry_ref()->tag()));
00587         T.ins( br );
00588     }
00589 
00590     if ( equivalence_ref() != 0) {
00591         br = new BinRep(new List<BinRep>);
00592         br->to_tuple().ins_last(new BinRep( "equivalence" ));
00593         br->to_tuple().ins_last(new BinRep( equivalence_ref()->name_ref()));
00594         T.ins( br );
00595     }
00596 
00597     if ( common_ref() != 0) {
00598         br = new BinRep(new List<BinRep>);
00599         br->to_tuple().ins_last(new BinRep( "common" ));
00600         br->to_tuple().ins_last(new BinRep( common_ref()->name_ref()));
00601         T.ins( br );
00602     }
00603 
00604     if ( intrinsic() == IS_INTRINSIC ) {
00605         br = new BinRep(new List<BinRep>);
00606         br->to_tuple().ins_last(new BinRep( "intrinsic" ));
00607         br->to_tuple().ins_last(new BinRep( "T" ));
00608         T.ins( br );
00609     }
00610 
00611     if ( external() == IS_EXTERNAL ) {
00612         br = new BinRep(new List<BinRep>);
00613         br->to_tuple().ins_last(new BinRep( "external" ));
00614         br->to_tuple().ins_last(new BinRep( "T" ));
00615         T.ins( br );
00616     }
00617 
00618     if ( formal() == IS_FORMAL ) {
00619         br = new BinRep(new List<BinRep>);
00620         br->to_tuple().ins_last(new BinRep( "formal" ));
00621         br->to_tuple().ins_last(new BinRep( "T" ));
00622         T.ins( br );
00623     }
00624 
00625     if ( global() == IS_GLOBAL ) {
00626         br = new BinRep(new List<BinRep>);
00627         br->to_tuple().ins_last(new BinRep( "global" ));
00628         br->to_tuple().ins_last(new BinRep( "T" ));
00629         T.ins( br );
00630     }
00631 
00632     if ( allocatable() == IS_ALLOCATABLE ) {
00633         br = new BinRep(new List<BinRep>);
00634         br->to_tuple().ins_last(new BinRep( "allocatable" ));
00635         br->to_tuple().ins_last(new BinRep( "T" ));
00636         T.ins( br );
00637     }
00638 
00639     switch (type().data_type()) {
00640     case UNKNOWN_TYPE:
00641     case UNDEFINED_TYPE:
00642         break;
00643 
00644     default:
00645         br = new BinRep(new List<BinRep>);
00646         br->to_tuple().ins_last(new BinRep( "type" ));
00647         br->to_tuple().ins_last(new BinRep( type().name_ref() ));
00648         T.ins( br );
00649 
00650         br = new BinRep(new List<BinRep>);
00651         br->to_tuple().ins_last(new BinRep( "size" ));
00652         br->to_tuple().ins_last(new BinRep( type().size()));
00653         T.ins( br );
00654     }
00655 }
00656 
00657 void
00658 Symbol::renaming_suggestion(String & new_name)
00659 {
00660     char            buf[20];
00661 
00662     sprintf(buf, "%d", ++_last_renaming_append);
00663     new_name = _tag;
00664     new_name += buf;
00665 }
00666 
00667 
00668 /// class ProgramSymbol
00669 
00670 ProgramSymbol &
00671 ProgramSymbol::operator = (const ProgramSymbol & psym) 
00672 {
00673     _last_renaming_append = -1;
00674     _tag = psym._tag;
00675 
00676     if (_overflow)
00677         delete _overflow;
00678 
00679     _overflow = ((psym._overflow) ? new BinRep(*psym._overflow) : 0);
00680 
00681     _entry = psym._entry;
00682 
00683     return *this;
00684 }
00685 
00686 Symbol         *
00687 ProgramSymbol::clone() const
00688 {
00689     return new ProgramSymbol(*this);
00690 }
00691 
00692 Symbol         *
00693 ProgramSymbol::clone_all() const
00694 {
00695     return new ProgramSymbol(*this);
00696 }
00697 
00698 
00699 ProgramSymbol::~ProgramSymbol()
00700 {
00701     /// ...  nothing to do (_entry should NOT be deleted)
00702 }
00703 
00704 const Statement      *
00705 ProgramSymbol::entry_ref() const
00706 {
00707     return _entry;
00708 }
00709 
00710 Statement      *
00711 ProgramSymbol::entry_ref()
00712 {
00713     return _entry;
00714 }
00715 
00716 void
00717 ProgramSymbol::entry(Statement * s)
00718 {
00719     /// ...  Old _entry should NOT be deleted
00720     _entry = s;
00721 }
00722 
00723 const Type &
00724 ProgramSymbol::type() const
00725 {
00726      Type *undef_type = new Type(make_type(VOID_TYPE));
00727      return *undef_type;
00728 ///   Type t(make_type(VOID_TYPE));
00729 ///   return make_type(VOID_TYPE);
00730 }
00731 
00732 void
00733 ProgramSymbol::print(ostream & o) const
00734 {
00735     o << "[sym \"" << _tag << "\" (class PROGRAM)";
00736 
00737     /// ...  the _entry field
00738     o << ", entry=";
00739 
00740     if (_entry)
00741         o << _entry->tag();
00742     else
00743         o << "Null";
00744 
00745     /// ...  the _overflow field
00746     if (_overflow)
00747         o << ", overflow=" << *_overflow;
00748 
00749     o << "]";
00750 }
00751 
00752 void
00753 ProgramSymbol::exchange_convert( VDL &vdl )
00754 {
00755     Symbol::exchange_convert( vdl );
00756 
00757     BinRep *b = CASTAWAY(BinRep *) vdl.data_ref();
00758 
00759     Set<BinRep> & S = b->find_ref("symtab")->find_ref( name_ref() )->to_set();
00760 
00761     BinRep *br = new BinRep(new List<BinRep>);
00762     br->to_tuple().ins_last(new BinRep( "class" ));
00763     br->to_tuple().ins_last(new BinRep( "PROGRAM" ));
00764     S.ins( br );
00765 }
00766 
00767 void
00768 ProgramSymbol::fill_in(const BinRep & binstr,
00769                        ExprTable & NOTUSED(exprs),
00770                        const Dictionary<VoidPtrDef>& stmts,
00771                        const Dictionary<VoidPtrDef>& NOTUSED(commons),
00772                        const Dictionary<VoidPtrDef>& NOTUSED(equivalences))
00773 {
00774     _entry = 0;
00775 
00776     if (_overflow)
00777         delete _overflow;
00778 
00779     _overflow = 0;
00780 
00781     for (Iterator<BinRep> iter = binstr.to_set(); iter.valid(); ++iter) {
00782         String          field;
00783 
00784         iter.current()[0].to_string(field);
00785 
00786         if (field == "class") {
00787             String          class_type;
00788 
00789             iter.current()[1].to_string(class_type);
00790 
00791             p_assert(class_type == "PROGRAM", "not of class PROGRAM");
00792         }
00793         else if (field == "entry") {
00794             String          entry_str;
00795 
00796             iter.current()[1].to_string(entry_str);
00797             _entry = (Statement *) stmts[entry_str].ptr_ref();
00798         }
00799         else {
00800             /// ...  Unrecognized -- add to overflow
00801 
00802             warn_overflow_map("ProgramSymbol", iter.current());
00803 
00804             if (!_overflow) {
00805                 _overflow = new BinRep;
00806                 Set<BinRep> *S = new Set<BinRep>;
00807                 _overflow->put_set( S );
00808             }
00809             _overflow->ins(iter.current());
00810         }
00811     }
00812 }
00813 
00814 int
00815 ProgramSymbol::structures_OK() const
00816 {
00817     if (!Symbol::structures_OK())
00818         return 0;
00819 
00820     CHECK_PTR_STRUCTURES(ProgramSymbol, _entry);
00821 
00822     return 1;
00823 }
00824 
00825 void
00826 ProgramSymbol::relink_dptrs(ProgramUnit & p)
00827 {
00828     if (_entry) {
00829         _entry = p.stmts().find_ref(_entry->tag());
00830     p_assert(_entry, "ProgramSymbol has NULL pointer");
00831       }
00832 }
00833 
00834 
00835 /// class FunctionSymbol
00836 
00837 FunctionSymbol::FunctionSymbol(const char *name,
00838                                const Type & type,
00839                                EXTERNAL_BOOL external,
00840                                INTRINSIC_BOOL intrinsic,
00841                                FORMAL_BOOL formal,
00842                                Statement * entry GIV(0))
00843     : Symbol(name, FUNCTION_CLASS)
00844 {
00845     _equivalence = 0;
00846 
00847     _type = type;
00848 
00849     _external = external;
00850     _intrinsic = intrinsic;
00851     _formal = formal;
00852     _entry = entry;
00853 }
00854 
00855 FunctionSymbol::FunctionSymbol(const FunctionSymbol & fsym)
00856     : Symbol(fsym._tag, FUNCTION_CLASS)
00857 {
00858     *this = fsym;
00859 }
00860 
00861 FunctionSymbol::~FunctionSymbol()
00862 {
00863     /// ...  nothing to do (_entry should NOT be deleted)
00864 }
00865 
00866 Symbol         *
00867 FunctionSymbol::clone() const
00868 {
00869     FunctionSymbol *s =  new FunctionSymbol(*this);
00870 
00871     s->_equivalence = 0;
00872 
00873     return s;
00874 }
00875 
00876 Symbol         *
00877 FunctionSymbol::clone_all() const
00878 {
00879     return new FunctionSymbol(*this);
00880 }
00881 
00882 
00883 FunctionSymbol &
00884 FunctionSymbol::operator = (const FunctionSymbol & fsym) 
00885 {
00886     _last_renaming_append = -1;
00887     _tag = fsym._tag;
00888 
00889     if (_overflow)
00890         delete _overflow;
00891 
00892     _overflow = (fsym._overflow ? new BinRep(*fsym._overflow) : 0);
00893 
00894     _equivalence = fsym._equivalence;
00895     _external = fsym._external;
00896     _intrinsic = fsym._intrinsic;
00897     _formal = fsym._formal;
00898     _entry = fsym._entry;
00899     _type = fsym._type;
00900 
00901     return *this;
00902 }
00903 
00904 EXTERNAL_BOOL
00905 FunctionSymbol::external() const
00906 {
00907     return (EXTERNAL_BOOL) _external;
00908 }
00909 
00910 void
00911 FunctionSymbol::external(EXTERNAL_BOOL ourbool)
00912 {
00913     _external = ourbool;
00914 }
00915 
00916 INTRINSIC_BOOL
00917 FunctionSymbol::intrinsic() const
00918 {
00919     return (INTRINSIC_BOOL) _intrinsic;
00920 }
00921 
00922 void
00923 FunctionSymbol::intrinsic(INTRINSIC_BOOL ourbool)
00924 {
00925     _intrinsic = ourbool;
00926 }
00927 
00928 FORMAL_BOOL
00929 FunctionSymbol::formal() const
00930 {
00931     return (FORMAL_BOOL) _formal;
00932 }
00933 
00934 void
00935 FunctionSymbol::formal(FORMAL_BOOL ourbool)
00936 {
00937     _formal = ourbool;
00938 }
00939 
00940 const Statement      *
00941 FunctionSymbol::entry_ref() const
00942 {
00943     return _entry;
00944 }
00945 
00946 Statement      *
00947 FunctionSymbol::entry_ref() 
00948 {
00949     return _entry;
00950 }
00951 
00952 void
00953 FunctionSymbol::entry(Statement * s)
00954 {
00955     _entry = s;
00956 }
00957 
00958 const Type &
00959 FunctionSymbol::type() const
00960 {
00961     return _type;
00962 }
00963 
00964 void
00965 FunctionSymbol::type(const Type & type)
00966 {
00967     _type = type;
00968 }
00969 
00970 Equivalence    *
00971 FunctionSymbol::equivalence_ref() const
00972 {
00973     return _equivalence;
00974 }
00975 
00976 void
00977 FunctionSymbol::equivalence(Equivalence & e, int  byte_base)
00978 {
00979     /// ...  Return if no change to be made
00980     if (&e == _equivalence)
00981         return;
00982 
00983     /// ...  Delete from old equivalence if it was in one
00984     clear_equivalence();
00985 
00986     /// ...  Add to new equivalence class
00987     /// ...  Insert into equivalence's list
00988     e._members.ins_first(new EquivalenceMember(*this, byte_base));
00989 
00990     /// ...  Point to the equivalence
00991     _equivalence = &e;
00992 }
00993 
00994 void
00995 FunctionSymbol::clear_equivalence()
00996 {
00997     /// ...  Delete from old equivalence if it was in one
00998 
00999     if (_equivalence) {
01000         EquivalenceMember *mem;
01001 
01002         if ((mem = _equivalence->find_ref(*this)) != 0) 
01003             _equivalence->_members.del(*mem);
01004         else {
01005 #if 0
01006             // No longer an error 6/8/94.
01007             //
01008             cerr << "Error: FunctionSymbol: Tried to delete symbol "
01009                  << *this << " from equivalence class "
01010                  << *_equivalence << ", but could not find the symbol in the "
01011                  << "equivalence.\n";
01012 
01013             p_abort("(see above message)");
01014 #endif
01015         }
01016     }
01017 
01018     _equivalence = 0;
01019 }
01020 
01021 int
01022 FunctionSymbol::is_entry()
01023 {
01024     return !_external && !_intrinsic;
01025 }
01026 
01027 void
01028 FunctionSymbol::print(ostream & o) const
01029 {
01030     o << "[sym \"" << _tag << "\" (class FUNCTION)";
01031 
01032     String          type_str;
01033 
01034     _type.format(type_str);
01035     o << ", type=" << type_str;
01036 
01037     /// ...  the _intrinsic field
01038     if (_intrinsic)
01039         o << ", Intrinsic";
01040 
01041     /// ...  the _external field
01042     if (_external)
01043         o << ", External";
01044 
01045     /// ...  the _formal field
01046     if (_formal)
01047         o << ", Formal";
01048 
01049     /// ...  the _entry field
01050     o << ", entry=";
01051 
01052     if (_entry)
01053         o << _entry->tag();
01054     else
01055         o << "Null";
01056 
01057     /// ...  _equivalence field
01058     if (_equivalence)
01059         o << ", equiv=" << _equivalence->name_ref();
01060 
01061     /// ...  the _overflow field
01062     if (_overflow)
01063         o << ", overflow=" << *_overflow;
01064 
01065     o << "]";
01066 }
01067 
01068 void
01069 FunctionSymbol::exchange_convert( VDL &vdl )
01070 {
01071     Symbol::exchange_convert( vdl );
01072 
01073     BinRep *b = CASTAWAY(BinRep *) vdl.data_ref();
01074 
01075     Set<BinRep> & S = b->find_ref("symtab")->find_ref( name_ref() )->to_set();
01076 
01077     BinRep *br = new BinRep(new List<BinRep>);
01078     br->to_tuple().ins_last(new BinRep( "class" ));
01079     br->to_tuple().ins_last(new BinRep( "ROUTINE" ));
01080     S.ins( br );
01081 }
01082 
01083 void
01084 FunctionSymbol::fill_in(const BinRep & binstr,
01085                         ExprTable & NOTUSED(exprs),
01086                         const Dictionary<VoidPtrDef>& stmts,
01087                         const Dictionary<VoidPtrDef>& NOTUSED(commons),
01088                         const Dictionary<VoidPtrDef>& equivalences)
01089 {
01090     if (_overflow)
01091         delete _overflow;
01092 
01093     _overflow = 0;
01094 
01095     _type.set(UNDEFINED_TYPE);
01096     _entry = 0;
01097     _equivalence = 0;
01098     _intrinsic = _external = _formal = 0;
01099 
01100     String          type_declaration;
01101     int             size_declaration = 0;
01102     int             size_was_defaulted = 0;
01103 
01104     for (Iterator<BinRep> iter = binstr.to_set(); iter.valid(); ++iter) {
01105         String          field;
01106 
01107         iter.current()[0].to_string(field);
01108 
01109         if (field == "class") {
01110             String          class_type;
01111 
01112             iter.current()[1].to_string(class_type);
01113 
01114             p_assert(class_type == "ROUTINE", "not of class ROUTINE");
01115         }
01116         else if (field == "entry") {
01117             String          entry_str;
01118 
01119             iter.current()[1].to_string(entry_str);
01120             _entry = (Statement *) stmts[entry_str].ptr_ref();
01121         }
01122         else if (field == "equivalence") {
01123             String          equiv_str;
01124 
01125             iter.current()[1].to_string(equiv_str);
01126             _equivalence = (Equivalence *) equivalences[equiv_str].ptr_ref();
01127         }
01128         else if (field == "intrinsic") {
01129             _intrinsic = convert_true_false(iter.current()[1], binstr);
01130         }
01131         else if (field == "external") {
01132             _external = convert_true_false(iter.current()[1], binstr);
01133         }
01134         else if (field == "formal") {
01135             _formal = convert_true_false(iter.current()[1], binstr);
01136         }
01137         else if (field == "type") {
01138             /// ...  Save this field for later processing
01139             iter.current()[1].to_string(type_declaration);
01140         }
01141         else if (field == "size") {
01142             /// ...  Save this field for later processing
01143             size_declaration = _get_size(iter.current()[1], binstr);
01144         }
01145         else if (field == "sizedef") {
01146             size_was_defaulted = convert_true_false(iter.current()[1], binstr);
01147         }
01148         else {
01149             /// ...  Unrecognized -- add to overflow
01150 
01151             warn_overflow_map("FunctionSymbol", iter.current());
01152 
01153             if (!_overflow) {
01154                 _overflow = new BinRep;
01155                 Set<BinRep> *S = new Set<BinRep>;
01156                 _overflow->put_set( S );
01157             }
01158             _overflow->ins(iter.current());
01159         }
01160     }
01161 
01162     /// ...  Now process the _type field
01163 
01164     if (!type_declaration.defined()) {
01165         cerr << "Error: FunctionSymbol::FunctionSymbol: No type was declared "
01166              << "for binstr object: " << binstr << endl;
01167 
01168         p_abort("(see above message)");
01169     }
01170 
01171     if (size_was_defaulted)
01172         _type.set(type_declaration);
01173     else
01174         _type.set(type_declaration, size_declaration);
01175 }
01176 
01177 int
01178 FunctionSymbol::structures_OK() const
01179 {
01180     if (!Symbol::structures_OK())
01181         return 0;
01182 
01183     CHECK_PTR_STRUCTURES(FunctionSymbol, _entry);
01184     CHECK_PTR_STRUCTURES(FunctionSymbol, _equivalence);
01185     CHECK_STRUCTURES(FunctionSymbol, _type);
01186 
01187     return 1;
01188 }
01189 
01190 void
01191 FunctionSymbol::relink_dptrs(ProgramUnit & p)
01192 {
01193     if (_entry) {
01194         _entry = p.stmts().find_ref(_entry->tag());
01195     p_assert(_entry, "FunctionSymbol has NULL pointer");
01196       }
01197 }
01198 
01199 
01200 /// class SubroutineSymbol
01201 
01202 SubroutineSymbol::SubroutineSymbol(const char *name,
01203                                    EXTERNAL_BOOL external,
01204                                    INTRINSIC_BOOL intrinsic,
01205                                    FORMAL_BOOL formal,
01206                                    Statement * entry GIV(0))
01207     : Symbol(name, SUBROUTINE_CLASS)
01208 {
01209     _entry = entry;
01210     _external = external;
01211     _intrinsic = intrinsic;
01212     _formal = formal;
01213 }
01214 
01215 SubroutineSymbol::SubroutineSymbol(const SubroutineSymbol & rsym)
01216     : Symbol(rsym._tag, SUBROUTINE_CLASS)
01217 {
01218     *this = rsym;
01219 }
01220 
01221 SubroutineSymbol::~SubroutineSymbol()
01222 {
01223     /// ...  nothing to do (_entry should NOT be deleted)
01224 }
01225 
01226 SubroutineSymbol &
01227 SubroutineSymbol::operator = (const SubroutineSymbol & rsym) 
01228 {
01229     _last_renaming_append = -1;
01230     _tag = rsym._tag;
01231 
01232     if (_overflow)
01233         delete _overflow;
01234 
01235     _overflow = ((rsym._overflow) ? new BinRep(*rsym._overflow) : 0);
01236 
01237     _external = rsym._external;
01238     _intrinsic = rsym._intrinsic;
01239     _entry = rsym._entry;
01240     _formal = rsym._formal;
01241 
01242     return *this;
01243 }
01244 
01245 const Type &
01246 SubroutineSymbol::type() const
01247 {
01248     Type *undef_type = new Type(make_type(VOID_TYPE));
01249     return *undef_type;
01250 }
01251 
01252 Symbol         *
01253 SubroutineSymbol::clone() const
01254 {
01255     return new SubroutineSymbol(*this);
01256 }
01257 
01258 Symbol         *
01259 SubroutineSymbol::clone_all() const
01260 {
01261     return new SubroutineSymbol(*this);
01262 }
01263 
01264 EXTERNAL_BOOL
01265 SubroutineSymbol::external() const
01266 {
01267     return (EXTERNAL_BOOL) _external;
01268 }
01269 
01270 void
01271 SubroutineSymbol::external(EXTERNAL_BOOL ourbool)
01272 {
01273     _external = ourbool;
01274 }
01275 
01276 INTRINSIC_BOOL
01277 SubroutineSymbol::intrinsic() const
01278 {
01279     return (INTRINSIC_BOOL) _intrinsic;
01280 }
01281 
01282 void
01283 SubroutineSymbol::intrinsic(INTRINSIC_BOOL ourbool)
01284 {
01285     _intrinsic = ourbool;
01286 }
01287 
01288 FORMAL_BOOL
01289 SubroutineSymbol::formal() const
01290 {
01291     return (FORMAL_BOOL) _formal;
01292 }
01293 
01294 void
01295 SubroutineSymbol::formal(FORMAL_BOOL ourbool)
01296 {
01297     _formal = ourbool;
01298 }
01299 
01300 const Statement      *
01301 SubroutineSymbol::entry_ref() const
01302 {
01303     return _entry;
01304 }
01305 
01306 Statement      *
01307 SubroutineSymbol::entry_ref() 
01308 {
01309     return _entry;
01310 }
01311 
01312 void
01313 SubroutineSymbol::entry(Statement * entry)
01314 {
01315     _entry = entry;
01316 }
01317 
01318 int
01319 SubroutineSymbol::is_entry()
01320 {
01321     return !_external && !_intrinsic;
01322 }
01323 
01324 void
01325 SubroutineSymbol::print(ostream & o) const
01326 {
01327     o << "[sym \"" << _tag << "\" (class SUBROUTINE)";
01328 
01329     /// ...  the _intrinsic field
01330     if (_intrinsic)
01331         o << ", Intrinsic";
01332 
01333     /// ...  the _external field
01334     if (_external)
01335         o << ", External";
01336 
01337     /// ...  the _formal field
01338     if (_formal)
01339         o << ", Formal";
01340 
01341     /// ...  the _entry field
01342     o << ", entry=";
01343     if (_entry)
01344         o << _entry->tag();
01345     else
01346         o << "Null";
01347 
01348     /// ...  the _overflow field
01349     if (_overflow)
01350         o << ", overflow=" << *_overflow;
01351 
01352     o << "]";
01353 }
01354 
01355 void
01356 SubroutineSymbol::exchange_convert( VDL &vdl )
01357 {
01358     Symbol::exchange_convert( vdl );
01359 
01360     BinRep *b = CASTAWAY(BinRep *) vdl.data_ref();
01361 
01362     Set<BinRep> & S = b->find_ref("symtab")->find_ref( name_ref() )->to_set();
01363 
01364     BinRep *br = new BinRep(new List<BinRep>);
01365     br->to_tuple().ins_last(new BinRep( "class" ));
01366     br->to_tuple().ins_last(new BinRep( "ROUTINE" ));
01367     S.ins( br );
01368 }
01369 
01370 void
01371 SubroutineSymbol::fill_in(const BinRep & binstr,
01372                           ExprTable & NOTUSED(exprs),
01373                           const Dictionary<VoidPtrDef>& stmts,
01374                           const Dictionary<VoidPtrDef>& NOTUSED(commons),
01375                           const Dictionary<VoidPtrDef>& NOTUSED(equivalences))
01376 {
01377     if (_overflow)
01378         delete _overflow;
01379 
01380     _overflow = 0;
01381 
01382     _entry = 0;
01383     _intrinsic = _external = _formal = 0;
01384 
01385     for (Iterator<BinRep> iter = binstr.to_set(); iter.valid(); ++iter) {
01386         String          field;
01387 
01388         iter.current()[0].to_string(field);
01389     
01390         if (field == "class") {
01391             String          class_type;
01392 
01393             iter.current()[1].to_string(class_type);
01394             p_assert(class_type == "ROUTINE", "not of class ROUTINE");
01395         }
01396         else if (field == "entry") {
01397             String          entry_str;
01398 
01399             iter.current()[1].to_string(entry_str);
01400             _entry = (Statement *) stmts[entry_str].ptr_ref();
01401         }
01402         else if (field == "intrinsic") {
01403             _intrinsic = convert_true_false(iter.current()[1], binstr);
01404         }
01405         else if (field == "external") {
01406             _external = convert_true_false(iter.current()[1], binstr);
01407         }
01408         else if (field == "formal") {
01409             _formal = convert_true_false(iter.current()[1], binstr);
01410         }
01411         else if (field == "sizedef") { 
01412         /// ...  nothing to do
01413     }
01414         else {
01415             /// ...  Unrecognized -- add to overflow
01416 
01417             warn_overflow_map("SubroutineSymbol", iter.current());
01418 
01419             if (!_overflow) {
01420                 _overflow = new BinRep;
01421                 Set<BinRep> *S = new Set<BinRep>;
01422                 _overflow->put_set( S );
01423             }
01424             _overflow->ins(iter.current());
01425         }
01426     }
01427 }
01428 
01429 int
01430 SubroutineSymbol::structures_OK() const
01431 {
01432     if (!Symbol::structures_OK())
01433         return 0;
01434 
01435     CHECK_PTR_STRUCTURES(SubroutineSymbol, _entry);
01436 
01437     return 1;
01438 }
01439 
01440 void
01441 SubroutineSymbol::relink_dptrs(ProgramUnit & p)
01442 {
01443     if (_entry && _entry->stmt_class() != UNDEFINED_STMT &&
01444     _entry->tag() && _entry->tag_defined()) {
01445         _entry = p.stmts().find_ref(_entry->tag());
01446     p_assert(_entry, "SubroutineSymbol has NULL pointer");
01447       }
01448 }
01449 
01450 
01451 /// Class VariableSymbol
01452 
01453 VariableSymbol::VariableSymbol(const char *name,
01454                                const Type & type,
01455                                FORMAL_BOOL formal,
01456                                SAVED_BOOL saved,
01457                                ArrayBounds * bounds1 GIV(0),
01458                                ArrayBounds * bounds2 GIV(0),
01459                                ArrayBounds * bounds3 GIV(0),
01460                                ArrayBounds * bounds4 GIV(0),
01461                                ArrayBounds * bounds5 GIV(0),
01462                                ArrayBounds * bounds6 GIV(0),
01463                                ArrayBounds * bounds7 GIV(0))
01464     : Symbol(name, VARIABLE_CLASS)
01465 {
01466     _equivalence = 0;
01467     _common = 0;
01468 
01469     _type = type;
01470 
01471     _shared_expr = 0;   /// ... _
01472     _gsa_base_symbol = 0;
01473 
01474     _formal = formal;
01475     _allocatable = 0;
01476     _saved = saved;
01477     _initial_value = 0;
01478     _global = NOT_GLOBAL;
01479 
01480     if (bounds1)
01481         _dim.ins_last(bounds1);
01482     if (bounds2)
01483         _dim.ins_last(bounds2);
01484     if (bounds3)
01485         _dim.ins_last(bounds3);
01486     if (bounds4)
01487         _dim.ins_last(bounds4);
01488     if (bounds5)
01489         _dim.ins_last(bounds5);
01490     if (bounds6)
01491         _dim.ins_last(bounds6);
01492     if (bounds7)
01493         _dim.ins_last(bounds7);
01494 
01495     _type.redimension(_dim.entries());
01496 }
01497 
01498 VariableSymbol::VariableSymbol(const char *name,
01499                                const Type & type,
01500                                FORMAL_BOOL formal,
01501                                SAVED_BOOL saved,
01502                    GLOBAL_BOOL global,
01503                                ArrayBounds * bounds1 GIV(0),
01504                                ArrayBounds * bounds2 GIV(0),
01505                                ArrayBounds * bounds3 GIV(0),
01506                                ArrayBounds * bounds4 GIV(0),
01507                                ArrayBounds * bounds5 GIV(0),
01508                                ArrayBounds * bounds6 GIV(0),
01509                                ArrayBounds * bounds7 GIV(0))
01510     : Symbol(name, VARIABLE_CLASS)
01511 {
01512     _equivalence = 0;
01513     _common = 0;
01514 
01515     _type = type;
01516     _gsa_base_symbol = 0;
01517 
01518     _formal = formal;
01519     _allocatable = 0;
01520     _saved = saved;
01521     _initial_value = 0;
01522     _global = global;
01523 
01524     if (bounds1)
01525         _dim.ins_last(bounds1);
01526     if (bounds2)
01527         _dim.ins_last(bounds2);
01528     if (bounds3)
01529         _dim.ins_last(bounds3);
01530     if (bounds4)
01531         _dim.ins_last(bounds4);
01532     if (bounds5)
01533         _dim.ins_last(bounds5);
01534     if (bounds6)
01535         _dim.ins_last(bounds6);
01536     if (bounds7)
01537         _dim.ins_last(bounds7);
01538 
01539     _type.redimension(_dim.entries());
01540 }
01541 
01542 VariableSymbol::VariableSymbol(const char *name,
01543                                const Type & type,
01544                                FORMAL_BOOL formal,
01545                                SAVED_BOOL saved,
01546                    GLOBAL_BOOL global,
01547                                ArrayDims * dims)
01548     : Symbol(name, VARIABLE_CLASS)
01549 {
01550     _equivalence = 0;
01551     _common = 0;
01552 
01553     _type = type;
01554 
01555     _shared_expr = 0;   /// ... _
01556     _gsa_base_symbol = 0;
01557 
01558     _formal = formal;
01559     _saved = saved;
01560     _initial_value = 0;
01561     _allocatable = 0;
01562     _global = global;
01563 
01564     _dim = *dims;
01565 
01566     _type.redimension(_dim.entries());
01567 }
01568 
01569 VariableSymbol::VariableSymbol(const char *name,
01570                                const Type & type,
01571                    ALLOC_BOOL allocatable,
01572                                FORMAL_BOOL formal,
01573                                SAVED_BOOL saved,
01574                                ArrayBounds * bounds1 GIV(0),
01575                                ArrayBounds * bounds2 GIV(0),
01576                                ArrayBounds * bounds3 GIV(0),
01577                                ArrayBounds * bounds4 GIV(0),
01578                                ArrayBounds * bounds5 GIV(0),
01579                                ArrayBounds * bounds6 GIV(0),
01580                                ArrayBounds * bounds7 GIV(0))
01581     : Symbol(name, VARIABLE_CLASS)
01582 {
01583     _equivalence = 0;
01584     _common = 0;
01585 
01586     _type = type;
01587 
01588     _shared_expr = 0;   /// ... _
01589     _gsa_base_symbol = 0;
01590 
01591     _formal = formal;
01592     _allocatable = allocatable;
01593     _saved = saved;
01594     _initial_value = 0;
01595     _global = NOT_GLOBAL;
01596 
01597     if (bounds1)
01598         _dim.ins_last(bounds1);
01599     if (bounds2)
01600         _dim.ins_last(bounds2);
01601     if (bounds3)
01602         _dim.ins_last(bounds3);
01603     if (bounds4)
01604         _dim.ins_last(bounds4);
01605     if (bounds5)
01606         _dim.ins_last(bounds5);
01607     if (bounds6)
01608         _dim.ins_last(bounds6);
01609     if (bounds7)
01610         _dim.ins_last(bounds7);
01611 
01612     _type.redimension(_dim.entries());
01613 }
01614 
01615 VariableSymbol::VariableSymbol(const char *name,
01616                                const Type & type,
01617                    ALLOC_BOOL allocatable,
01618                                FORMAL_BOOL formal,
01619                                SAVED_BOOL saved,
01620                    GLOBAL_BOOL global,
01621                                ArrayBounds * bounds1 GIV(0),
01622                                ArrayBounds * bounds2 GIV(0),
01623                                ArrayBounds * bounds3 GIV(0),
01624                                ArrayBounds * bounds4 GIV(0),
01625                                ArrayBounds * bounds5 GIV(0),
01626                                ArrayBounds * bounds6 GIV(0),
01627                                ArrayBounds * bounds7 GIV(0))
01628     : Symbol(name, VARIABLE_CLASS)
01629 {
01630     _equivalence = 0;
01631     _common = 0;
01632 
01633     _type = type;
01634 
01635     _formal = formal;
01636     _allocatable = allocatable;
01637     _saved = saved;
01638     _initial_value = 0;
01639     _global = global;
01640 
01641     _shared_expr = 0;   /// ... _
01642     _gsa_base_symbol = 0;
01643 
01644     if (bounds1)
01645         _dim.ins_last(bounds1);
01646     if (bounds2)
01647         _dim.ins_last(bounds2);
01648     if (bounds3)
01649         _dim.ins_last(bounds3);
01650     if (bounds4)
01651         _dim.ins_last(bounds4);
01652     if (bounds5)
01653         _dim.ins_last(bounds5);
01654     if (bounds6)
01655         _dim.ins_last(bounds6);
01656     if (bounds7)
01657         _dim.ins_last(bounds7);
01658 
01659     _type.redimension(_dim.entries());
01660 }
01661 
01662 VariableSymbol::VariableSymbol(const char *name,
01663                                const Type & type,
01664                    ALLOC_BOOL allocatable,
01665                                FORMAL_BOOL formal,
01666                                SAVED_BOOL saved,
01667                    GLOBAL_BOOL global,
01668                                ArrayDims * dims)
01669     : Symbol(name, VARIABLE_CLASS)
01670 {
01671     _equivalence = 0;
01672     _common = 0;
01673 
01674     _type = type;
01675 
01676     _shared_expr = 0;   /// ... _
01677     _gsa_base_symbol = 0;
01678 
01679     _formal = formal;
01680     _saved = saved;
01681     _initial_value = 0;
01682     _allocatable = allocatable;
01683     _global = global;
01684 
01685     _dim = *dims;
01686 
01687     _type.redimension(_dim.entries());
01688 }
01689 
01690 VariableSymbol::~VariableSymbol()
01691 {
01692     if (_shared_expr && 
01693     (_shared_expr->op() == ID_OP ||
01694      _shared_expr->op() == DISTRIBUTE_OP))
01695     delete _shared_expr;  /// ... _
01696 
01697     /// ...  Nothing else to do (_equivalence and _common should NOT be deleted)
01698 }
01699 
01700 VariableSymbol &
01701 VariableSymbol::operator = (const VariableSymbol & vsym) 
01702 {
01703     _last_renaming_append = -1;
01704     _tag = vsym._tag;
01705 
01706     if (_overflow)
01707         delete _overflow;
01708 
01709     _overflow = (vsym._overflow ? new BinRep(*vsym._overflow) : 0);
01710 
01711     _gsa_base_symbol = vsym._gsa_base_symbol;
01712 
01713     _type = vsym._type;
01714     _equivalence = vsym._equivalence;
01715     _dim = vsym._dim;
01716     _shared_dim = vsym._shared_dim;
01717     _formal = vsym._formal;
01718     _global = vsym._global;
01719     _allocatable = vsym._allocatable;
01720     _saved = vsym._saved;
01721     _common = vsym._common;
01722     _initial_value = vsym._initial_value;
01723 
01724     if (vsym._shared_expr)
01725     if (vsym._shared_expr->op() == ID_OP ||
01726         vsym._shared_expr->op() == DISTRIBUTE_OP)   /// ... _
01727         _shared_expr = vsym._shared_expr->clone();
01728     else
01729         _shared_expr = vsym._shared_expr;
01730     else
01731     _shared_expr = 0;
01732 
01733     return *this;
01734 }
01735 
01736 Symbol         *
01737 VariableSymbol::clone() const
01738 {
01739     VariableSymbol *s = new VariableSymbol(*this);
01740 
01741     s->_equivalence = 0;
01742     s->_common      = 0;
01743     s->_gsa_base_symbol = this->_gsa_base_symbol;
01744 
01745     if (s->_shared_expr) {
01746     if (s->_shared_expr->op() == ID_OP ||
01747         s->_shared_expr->op() == DISTRIBUTE_OP)
01748         delete s->_shared_expr;
01749     s->_shared_expr = 0;   /// ... _  cloned one must be private initially
01750     }
01751 
01752     return s;
01753 }
01754 
01755 Symbol         *
01756 VariableSymbol::clone_all() const
01757 {
01758     return new VariableSymbol(*this);
01759 }
01760 
01761 const Type &
01762 VariableSymbol::type() const
01763 {
01764     return _type;
01765 }
01766 
01767 void
01768 VariableSymbol::type(const Type & type)
01769 {
01770     _type = type;
01771 }
01772 
01773 Equivalence    *
01774 VariableSymbol::equivalence_ref() const
01775 {
01776     return _equivalence;
01777 }
01778 
01779 void
01780 VariableSymbol::equivalence(Equivalence & e, int  byte_base)
01781 {
01782     /// ...  Return if no change to be made
01783     if (&e == _equivalence)
01784         return;
01785 
01786     /// ...  Delete from old equivalence if it was in one
01787     clear_equivalence();
01788 
01789     /// ...  Add to new equivalence class
01790     /// ...  Insert into equivalence's list
01791     e._members.ins_first(new EquivalenceMember(*this, byte_base));
01792 
01793     /// ...  Point to the equivalence
01794     _equivalence = &e;
01795 }
01796 
01797 void
01798 VariableSymbol::clear_equivalence()
01799 {
01800     /// ...  Delete from old equivalence if it was in one
01801     if (_equivalence) {
01802         EquivalenceMember *mem;
01803 
01804         if ((mem = _equivalence->find_ref(*this)) != 0) 
01805             _equivalence->_members.del(*mem);
01806         else {
01807 #if 0
01808             // No longer an error: 6/8/94
01809             //
01810             cerr << "Error: VariableSymbol: Tried to delete symbol "
01811                  << *this << " from equivalence class "
01812                  << *_equivalence << ", but could not find the symbol in the "
01813                  << "equivalence." << endl;
01814 
01815             p_abort("(see above message)");
01816 #endif
01817         }
01818 
01819     }
01820 
01821     _equivalence = 0;
01822 }
01823 
01824 Expression *  /// ... _
01825 VariableSymbol::shared_expr() const
01826 {
01827     return _shared_expr;
01828 }
01829 
01830 void   /// ... _
01831 VariableSymbol::set_to_private()
01832 {
01833     _shared_expr = 0;    /// ...  go back to default value: private
01834 }
01835 
01836 void   /// ... _
01837 VariableSymbol::shared_expr(Expression *shared)
01838 {
01839     _shared_expr = shared;
01840 }
01841 
01842 const ArrayDims &
01843 VariableSymbol::dim() const
01844 {
01845     return (const ArrayDims &) _dim;
01846 }
01847 
01848 ArrayDims &
01849 VariableSymbol::dim() 
01850 {
01851     return (ArrayDims &) _dim;
01852 }
01853 
01854 const SharedDims &
01855 VariableSymbol::shared_dim() const
01856 {
01857     return (const SharedDims &) _shared_dim;
01858 }
01859 
01860 SharedDims &
01861 VariableSymbol::shared_dim() 
01862 {
01863     return (SharedDims &) _shared_dim;
01864 }
01865 
01866 FORMAL_BOOL
01867 VariableSymbol::formal() const
01868 {
01869     return (FORMAL_BOOL) _formal;
01870 }
01871 
01872 void
01873 VariableSymbol::formal(FORMAL_BOOL ourbool)
01874 {
01875     _formal = ourbool;
01876 }
01877 
01878 ALLOC_BOOL
01879 VariableSymbol::allocatable() const
01880 {
01881     return (ALLOC_BOOL) _allocatable;
01882 }
01883 
01884 void
01885 VariableSymbol::allocatable(ALLOC_BOOL ourbool)
01886 {
01887     _allocatable = ourbool;
01888 }
01889 
01890 GLOBAL_BOOL
01891 VariableSymbol::global() const
01892 {
01893     return (GLOBAL_BOOL) _global;
01894 }
01895 
01896 void
01897 VariableSymbol::global(GLOBAL_BOOL ourbool)
01898 {
01899     _global = ourbool;
01900 }
01901 
01902 INITIAL_BOOL
01903 VariableSymbol::initial_value() const
01904 {
01905     return (INITIAL_BOOL) _initial_value;
01906 }
01907 
01908 void
01909 VariableSymbol::initial_value(INITIAL_BOOL ourbool)
01910 {
01911     _initial_value = ourbool;
01912 }
01913 
01914 SAVED_BOOL
01915 VariableSymbol::saved() const
01916 {
01917     return (SAVED_BOOL) _saved;
01918 }
01919 
01920 void
01921 VariableSymbol::saved(SAVED_BOOL ourbool)
01922 {
01923     _saved = ourbool;
01924 }
01925 
01926 const CommonBlock    *
01927 VariableSymbol::common_ref() const
01928 {
01929     return _common;
01930 }
01931 
01932 CommonBlock    *
01933 VariableSymbol::common_ref() 
01934 {
01935     return _common;
01936 }
01937 
01938 void
01939 VariableSymbol::common(CommonBlock & cb, int  index)
01940 {
01941     /// ...  Return if no change to be made
01942     if (&cb == _common)
01943         return;
01944 
01945     /// ...  Delete from old common block if it was in one
01946     clear_common();
01947 
01948     /// ...  Add to new common block
01949     /// ...  Insert into common block's list
01950     cb._body.ins(*this, (int) index);
01951 
01952     /// ...  Point to the common block
01953     _common = &cb;
01954 }
01955 
01956 void
01957 VariableSymbol::clear_common()
01958 {
01959     /// ...  Delete from old common block if it was in one
01960 
01961     if (_common) {
01962         /// ...  Search for the symbol in the common block
01963         int             index = 0, found_index = -1;
01964 
01965         Iterator<Symbol> iter = _common->iterator();
01966 
01967         while (iter.valid()) {
01968             if (&iter.current() == this) {
01969                 found_index = index;
01970                 break;
01971             }
01972             ++index;
01973             ++iter;
01974         }
01975 
01976         if (found_index >= 0) 
01977             _common->_body.del((int) found_index);
01978     }
01979 
01980     _common = 0;
01981 }
01982 
01983 
01984 int
01985 VariableSymbol::is_scalar() const
01986 {
01987     return (_dim.entries() == 0);
01988 }
01989 
01990 int
01991 VariableSymbol::is_array() const
01992 {
01993     return (_dim.entries() > 0);
01994 }
01995 
01996 int
01997 VariableSymbol::is_shared() const
01998 {
01999     return (_shared_dim.entries() > 0);
02000 }
02001 
02002 int
02003 VariableSymbol::size() const
02004 {
02005     int total_size;
02006 
02007     total_size = type().size();
02008 
02009     if (is_array()) {
02010         for (Iterator<ArrayBounds> iter = dim(); iter.valid(); ++iter) {
02011             int          lb_value = 0, ub_value = 0;
02012 
02013             if (total_size > 0) {
02014                 Expression  *lb = iter.current().lower_ref();
02015 
02016                 if (lb == 0)
02017                     lb_value = 1;
02018                 else {
02019                     lb = simplify( replace_parameters(lb->clone()) );
02020                     if (lb->op() == INTEGER_CONSTANT_OP) 
02021                         lb_value = lb->value();
02022                     else
02023                         total_size = 0;
02024                     delete lb;
02025                 }
02026 
02027                 Expression  *ub = iter.current().upper_ref();
02028 
02029                 if (ub == 0)
02030                     total_size = 0;
02031                 else {
02032                     ub = simplify( replace_parameters(ub->clone()) );
02033                     if (ub->op() == INTEGER_CONSTANT_OP) 
02034                         ub_value = ub->value();
02035                     else
02036                         total_size = 0;
02037                     delete ub;
02038                 }
02039 
02040                 total_size = total_size * (ub_value - lb_value + 1);
02041             }
02042         }
02043     }
02044 
02045     return total_size;
02046 }
02047 
02048 void
02049 VariableSymbol::print(ostream & o) const
02050 {
02051     o << "[sym \"";
02052 
02053     o << _tag << "\" (class VARIABLE)";
02054 
02055     /// ...  the _type field
02056     o << ", type=";
02057     if (is_array())
02058         o << "ARRAY of ";
02059     o << _type;
02060 
02061     /// ...  the _formal field
02062     if (_formal)
02063         o << ", Formal";
02064 
02065     /// ...  the _global field
02066     if (_global)
02067         o << ", Global";
02068 
02069     /// ...  the _alloc field
02070     if (_allocatable)
02071         o << ", Allocatable";
02072 
02073     if (_initial_value)
02074     o << ", Initialized";
02075 
02076     /// ...  the _saved field
02077     if (_saved)
02078         o << ", Saved";
02079 
02080     /// ...  the _equivalence field
02081     if (_equivalence)
02082         o << ", equiv=" << _equivalence->name_ref();
02083 
02084     /// ...  the _common field
02085     if (_common)
02086         o << ", common=" << _common->name_ref();
02087 
02088     /// ...  the _dim field
02089     if (is_array())
02090         o << ", dim=" << _dim;
02091 
02092     /// ...  the _shared_dim field
02093     if (is_shared())
02094         o << ", shared_dim=" << _shared_dim;
02095 
02096     o << ", gsa_base_symbol=" << _gsa_base_symbol;
02097 
02098     /// ...  the _overflow field
02099     if (_overflow) 
02100         o << ", overflow=" << *_overflow;
02101 
02102     if (_shared_expr) {  /// ... _
02103     if(_shared_expr->op() == ID_OP ||
02104        _shared_expr->op() == DISTRIBUTE_OP) {
02105         o << ", SHARED";
02106     } else {
02107         o << ", PRIVATE";
02108     }
02109     }
02110 
02111     o << "]";
02112 }
02113 
02114 void
02115 VariableSymbol::exchange_convert( VDL &vdl )
02116 {
02117     Symbol::exchange_convert( vdl );
02118 
02119     BinRep *b = CASTAWAY(BinRep *) vdl.data_ref();
02120 
02121     Set<BinRep> & S = b->find_ref("symtab")->find_ref( name_ref() )->to_set();
02122 
02123     BinRep *br = new BinRep(new List<BinRep>);
02124     br->to_tuple().ins_last(new BinRep( "class" ));
02125     br->to_tuple().ins_last(new BinRep( "VARIABLE" ));
02126     S.ins( br );
02127 }
02128 
02129 void
02130 VariableSymbol::fill_in(const BinRep & binstr,
02131                         ExprTable & exprs,
02132                         const Dictionary<VoidPtrDef>& NOTUSED(stmts),
02133                         const Dictionary<VoidPtrDef>& commons,
02134                         const Dictionary<VoidPtrDef>& equivalences)
02135 {
02136     if (_overflow)
02137         delete _overflow;
02138 
02139     _overflow = 0;
02140 
02141     _type.set(UNDEFINED_TYPE);
02142 
02143     /// ...  Only zero the fields which haven't been set yet
02144     /// ...  _initial_value, if it exists, should have already been
02145     /// ...  set by this time, so it is not changed.
02146     
02147     _formal = 0;
02148     _global = 0;
02149     _gsa_base_symbol = 0;
02150     _allocatable  = 0;
02151     _equivalence = 0;
02152     _common = 0;
02153     _saved = 0;
02154 
02155     String          type_declaration;
02156     int             size_declaration = 0;
02157     int             size_was_defaulted = 0;
02158 
02159     for (Iterator<BinRep> iter = binstr.to_set(); iter.valid(); ++iter) {
02160         String          field;
02161 
02162         iter.current()[0].to_string(field);
02163     
02164         if (field == "class") {
02165             String          class_type;
02166 
02167             iter.current()[1].to_string(class_type);
02168 
02169             if (class_type == "UNKNOWN") {
02170                 cerr << "KAP/Polaris warning: "
02171                      << "[\"class\", \"UNKNOWN\"] assuming \"VARIABLE\""
02172                      << endl;
02173                 class_type = "VARIABLE";
02174             }
02175 
02176             p_assert(class_type == "VARIABLE", "not of class VARIABLE");
02177 
02178         }
02179         else if (field == "equivalence") {
02180             String          equiv_str;
02181 
02182             iter.current()[1].to_string(equiv_str);
02183             _equivalence = (Equivalence *) equivalences[equiv_str].ptr_ref();
02184         }
02185         else if (field == "common") {
02186             String          common_str;
02187 
02188             iter.current()[1].to_string(common_str);
02189             _common = (CommonBlock *) commons[common_str].ptr_ref();
02190         }
02191         else if (field == "formal") {
02192             _formal = convert_true_false(iter.current()[1], binstr);
02193         }
02194         else if (field == "global") {
02195             _global = convert_true_false(iter.current()[1], binstr);
02196         }
02197         else if (field == "allocatable") {
02198             _allocatable = convert_true_false(iter.current()[1], binstr);
02199         }
02200         else if (field == "saved") {
02201             _saved = convert_true_false(iter.current()[1], binstr);
02202         }
02203         else if (field == "dim") {
02204             _dim.convert( iter.current()[1], exprs);
02205         }
02206         else if (field == "type") {
02207             /// ...  Save this field for later processing
02208             iter.current()[1].to_string(type_declaration);
02209         }
02210         else if (field == "size") {
02211             /// ...  Save this field for later processing
02212             size_declaration = _get_size(iter.current()[1], binstr);
02213         }
02214         else if (field == "sizedef") {
02215             size_was_defaulted = convert_true_false(iter.current()[1], binstr);
02216         }
02217         else {
02218             /// ...  Unrecognized -- add to overflow
02219 
02220             warn_overflow_map("VariableSymbol", iter.current());
02221 
02222             if (!_overflow) {
02223                 _overflow = new BinRep;
02224                 Set<BinRep> *S = new Set<BinRep>;
02225                 _overflow->put_set( S );
02226             }
02227             _overflow->ins(iter.current());
02228         }
02229     }
02230 
02231     /// ...  Now process the _type field
02232 
02233     if (!type_declaration.defined()) {
02234         cerr << "KAP/Polaris warning:  No type was declared "
02235              << "assuming \"INTEGER\""
02236              << endl;
02237         type_declaration = "INTEGER";
02238     }
02239 
02240     if (size_was_defaulted)
02241         _type.set(type_declaration);
02242     else
02243         _type.set(type_declaration, size_declaration);
02244 }
02245 
02246 int
02247 VariableSymbol::structures_OK() const
02248 {
02249     if (!Symbol::structures_OK())
02250         return 0;
02251 
02252     CHECK_STRUCTURES(VariableSymbol, _type);
02253     CHECK_PTR_STRUCTURES(VariableSymbol, _equivalence);
02254     CHECK_PTR_STRUCTURES(VariableSymbol, _common);
02255     CHECK_STRUCTURES(VariableSymbol, _dim);
02256     CHECK_STRUCTURES(VariableSymbol, _shared_dim);
02257 
02258     return 1;
02259 }
02260 
02261 void
02262 VariableSymbol::relink_dptrs(ProgramUnit & p)
02263 {
02264     if (_equivalence) {
02265         _equivalence = p.equivalences().find_ref(_equivalence->name_ref());
02266     p_assert(_equivalence, "VariableSymbol has NULL equivalence pointer");
02267       }
02268 
02269     if (_common) {
02270         _common = p.common_blocks().find_ref(_common->name_ref());
02271     p_assert(_common, "VariableSymbol has NULL common pointer");
02272       }
02273 
02274     if (_gsa_base_symbol) {
02275     _gsa_base_symbol = p.symtab().find_ref(_gsa_base_symbol->name_ref());
02276     }
02277 
02278     Iterator<ArrayBounds> iter = _dim;
02279 
02280     while (iter.valid()) {
02281         if (iter.current().lower_ref())
02282             iter.current().lower_ref()->relink_eptrs(p);
02283         if (iter.current().upper_ref())
02284             iter.current().upper_ref()->relink_eptrs(p);
02285         ++iter;
02286     }
02287 
02288     /// ... _
02289     if (_shared_expr && 
02290     (_shared_expr->op() == ID_OP ||
02291      _shared_expr->op() == DISTRIBUTE_OP)) {
02292       Symbol * symref = p.symtab().find_ref(_tag);
02293       p_assert(symref, "VariableSymbol has NULL shared pointer");
02294       _shared_expr->symbol(*symref);
02295     }
02296 }
02297 
02298 
02299 /// Class PointerSymbol
02300 
02301 PointerSymbol::PointerSymbol(const char *name,
02302                                const Type & type,
02303                                FORMAL_BOOL formal,
02304                                SAVED_BOOL saved,
02305                                ArrayBounds * bounds1 GIV(0),
02306                                ArrayBounds * bounds2 GIV(0),
02307                                ArrayBounds * bounds3 GIV(0),
02308                                ArrayBounds * bounds4 GIV(0),
02309                                ArrayBounds * bounds5 GIV(0),
02310                                ArrayBounds * bounds6 GIV(0),
02311                                ArrayBounds * bounds7 GIV(0))
02312     : VariableSymbol(name, type, formal, saved,
02313              bounds1, bounds2, bounds3, bounds4, 
02314              bounds5, bounds6, bounds7)
02315 {
02316     _assoc_variable = 0;
02317 }
02318 
02319 PointerSymbol::PointerSymbol(const char *name,
02320                                const Type & type,
02321                                FORMAL_BOOL formal,
02322                                SAVED_BOOL saved,
02323                    GLOBAL_BOOL global,
02324                                ArrayBounds * bounds1 GIV(0),
02325                                ArrayBounds * bounds2 GIV(0),
02326                                ArrayBounds * bounds3 GIV(0),
02327                                ArrayBounds * bounds4 GIV(0),
02328                                ArrayBounds * bounds5 GIV(0),
02329                                ArrayBounds * bounds6 GIV(0),
02330                                ArrayBounds * bounds7 GIV(0))
02331     : VariableSymbol(name, type, formal, saved, global,
02332              bounds1, bounds2, bounds3, bounds4, 
02333              bounds5, bounds6, bounds7)
02334 {
02335     _assoc_variable = 0;
02336 }
02337 
02338 PointerSymbol::PointerSymbol(const char *name,
02339                  Symbol &assoc,
02340                  const Type & type,
02341                  FORMAL_BOOL formal,
02342                  SAVED_BOOL saved,
02343                  ArrayBounds * bounds1 GIV(0),
02344                  ArrayBounds * bounds2 GIV(0),
02345                  ArrayBounds * bounds3 GIV(0),
02346                  ArrayBounds * bounds4 GIV(0),
02347                  ArrayBounds * bounds5 GIV(0),
02348                  ArrayBounds * bounds6 GIV(0),
02349                  ArrayBounds * bounds7 GIV(0))
02350     : VariableSymbol(name, type, formal, saved,
02351              bounds1, bounds2, bounds3, bounds4, 
02352              bounds5, bounds6, bounds7)
02353 {
02354     _assoc_variable = &assoc;
02355 }
02356 
02357 PointerSymbol::PointerSymbol(const char *name,
02358                  Symbol &assoc,
02359                  const Type & type,
02360                  FORMAL_BOOL formal,
02361                  SAVED_BOOL saved,
02362                  GLOBAL_BOOL global,
02363                  ArrayBounds * bounds1 GIV(0),
02364                  ArrayBounds * bounds2 GIV(0),
02365                  ArrayBounds * bounds3 GIV(0),
02366                  ArrayBounds * bounds4 GIV(0),
02367                  ArrayBounds * bounds5 GIV(0),
02368                  ArrayBounds * bounds6 GIV(0),
02369                  ArrayBounds * bounds7 GIV(0))
02370     : VariableSymbol(name, type, formal, saved, global,
02371              bounds1, bounds2, bounds3, bounds4, 
02372              bounds5, bounds6, bounds7)
02373 {
02374     _assoc_variable = &assoc;
02375 }
02376 
02377 PointerSymbol::~PointerSymbol()
02378 {
02379     /// ...  Nothing to do 
02380 }
02381 
02382 PointerSymbol &
02383 PointerSymbol::operator = (const PointerSymbol & vsym) 
02384 {
02385     _last_renaming_append = -1;
02386     _tag = vsym._tag;
02387 
02388     if (_overflow)
02389         delete _overflow;
02390 
02391     _overflow = (vsym._overflow ? new BinRep(*vsym._overflow) : 0);
02392 
02393     _type = vsym._type;
02394     _equivalence = vsym._equivalence;
02395     _dim = vsym._dim;
02396     _shared_dim = vsym._shared_dim;
02397     _formal = vsym._formal;
02398     _global = vsym._global;
02399     _allocatable = vsym._allocatable;
02400     _saved = vsym._saved;
02401     _common = vsym._common;
02402     _initial_value = vsym._initial_value;
02403 
02404     _assoc_variable = vsym._assoc_variable;
02405 
02406     return *this;
02407 }
02408 
02409 Symbol         *
02410 PointerSymbol::clone() const
02411 {
02412     PointerSymbol *s = new PointerSymbol(*this);
02413 
02414     s->_equivalence = 0;
02415     s->_common      = 0;
02416 
02417     return s;
02418 }
02419 
02420 Symbol         *
02421 PointerSymbol::clone_all() const
02422 {
02423     return new PointerSymbol(*this);
02424 }
02425 
02426 const Symbol &
02427 PointerSymbol::assoc_variable() const
02428 {
02429     return *_assoc_variable;
02430 }
02431 
02432 Symbol &
02433 PointerSymbol::assoc_variable() 
02434 {
02435     return *_assoc_variable;
02436 }
02437 
02438 void
02439 PointerSymbol::print(ostream & o) const
02440 {
02441     o << "[sym \"";
02442 
02443     o << _tag << "\" (class VARIABLE)";
02444 
02445     if (_assoc_variable) {
02446     o << "[POINTER associated with " << _assoc_variable->name_ref() << "]";
02447     }
02448     else {
02449     o << "[POINTER not associated with a target]";
02450     }
02451 
02452     /// ...  the _type field
02453     o << ", type=";
02454     if (is_array())
02455         o << "ARRAY of ";
02456     o << _type;
02457 
02458     /// ...  the _formal field
02459     if (_formal)
02460         o << ", Formal";
02461 
02462     /// ...  the _allocatable field
02463     if (_allocatable)
02464     o << ", Allocatable";
02465     
02466     /// ...  the _global field
02467     if (_global)
02468         o << ", Global";
02469 
02470     if (_initial_value)
02471     o << ", Initialized";
02472 
02473     /// ...  the _saved field
02474     if (_saved)
02475         o << ", Saved";
02476 
02477     /// ...  the _equivalence field
02478     if (_equivalence)
02479         o << ", equiv=" << _equivalence->name_ref();
02480 
02481     /// ...  the _common field
02482     if (_common)
02483         o << ", common=" << _common->name_ref();
02484 
02485     /// ...  the _dim field
02486     if (is_array())
02487         o << ", dim=" << _dim;
02488 
02489     /// ...  the _shared_dim field
02490     if (is_shared())
02491         o << ", shared_dim=" << _shared_dim;
02492 
02493     /// ...  the _overflow field
02494     if (_overflow) 
02495         o << ", overflow=" << *_overflow;
02496 
02497     o << "]";
02498 }
02499 
02500 void
02501 PointerSymbol::exchange_convert( VDL &vdl )
02502 {
02503     Symbol::exchange_convert( vdl );
02504 
02505     VariableSymbol::exchange_convert( vdl );
02506 }
02507 
02508 void
02509 PointerSymbol::fill_in(const BinRep & binstr,
02510                         ExprTable & exprs,
02511                         const Dictionary<VoidPtrDef>& NOTUSED(stmts),
02512                         const Dictionary<VoidPtrDef>& commons,
02513                         const Dictionary<VoidPtrDef>& equivalences)
02514 {
02515     _assoc_variable = 0;
02516     static Dictionary<VoidPtrDef> *dummy = 0;
02517     VariableSymbol::fill_in(binstr, exprs, *dummy , commons, equivalences);
02518 }
02519 
02520 int
02521 PointerSymbol::structures_OK() const
02522 {
02523     if (!Symbol::structures_OK())
02524         return 0;
02525 
02526     if (!VariableSymbol::structures_OK())
02527     return 0;
02528     
02529     if (_assoc_variable) 
02530     return 1;
02531     else
02532     return 0;
02533 }
02534 
02535 void
02536 PointerSymbol::relink_dptrs(ProgramUnit & p)
02537 {
02538     if (_equivalence) {
02539         _equivalence = p.equivalences().find_ref(_equivalence->name_ref());
02540     p_assert(_equivalence, "PointerSymbol has NULL equivalence pointer");
02541       }
02542 
02543     if (_common) {
02544         _common = p.common_blocks().find_ref(_common->name_ref());
02545     p_assert(_common, "PointerSymbol has NULL common pointer");
02546       }
02547 
02548     Iterator<ArrayBounds> iter = _dim;
02549 
02550     while (iter.valid()) {
02551         if (iter.current().lower_ref())
02552             iter.current().lower_ref()->relink_eptrs(p);
02553         if (iter.current().upper_ref())
02554             iter.current().upper_ref()->relink_eptrs(p);
02555         ++iter;
02556     }
02557 
02558     if (_assoc_variable) {
02559     _assoc_variable = p.symtab().find_ref(_assoc_variable->name_ref());
02560     p_assert(_assoc_variable, "PointerSymbol has NULL assoc variable");
02561       }
02562 }
02563 
02564 
02565 /// class SymbolicConstantSymbol
02566 
02567 Symbol         *
02568 SymbolicConstantSymbol::clone() const
02569 {
02570     return new SymbolicConstantSymbol(*this);
02571 }
02572 
02573 Symbol         *
02574 SymbolicConstantSymbol::clone_all() const
02575 {
02576     return new SymbolicConstantSymbol(*this);
02577 }
02578 
02579 SymbolicConstantSymbol::~SymbolicConstantSymbol()
02580 {
02581     /// ...  Since _expr "lives" in the SymbolicConstantSymbol (it's not a
02582     /// ...  pointer to an Expression somewhere else), it must be deleted.
02583 
02584     if (_expr)
02585         delete _expr;
02586 
02587     _expr = 0;
02588 }
02589 
02590 const Type &
02591 SymbolicConstantSymbol::type() const
02592 {
02593     p_assert(_expr != 0, "SymbolicConstantSymbol::type(): _expr field is NULL");
02594 
02595     return (Type &) _type;
02596 }
02597 
02598 const Expression     *
02599 SymbolicConstantSymbol::expr_ref() const
02600 {
02601     return _expr;
02602 }
02603 
02604 Expression     *
02605 SymbolicConstantSymbol::expr_ref() 
02606 {
02607     return _expr;
02608 }
02609 
02610 void
02611 SymbolicConstantSymbol::expr(Expression * e)
02612 {
02613     if (_expr)
02614         delete _expr;
02615 
02616     _expr = e;
02617 }
02618 
02619 /// Check this function out
02620 
02621 SymbolicConstantSymbol &
02622 SymbolicConstantSymbol::operator = (const SymbolicConstantSymbol & scsym) 
02623 {
02624     _last_renaming_append = -1;
02625     _tag = scsym._tag;
02626 
02627     if (_overflow)
02628         delete _overflow;
02629 
02630     _overflow = ((scsym._overflow) ? new BinRep(*scsym._overflow) : 0);
02631 
02632     if (_expr)
02633         delete _expr;
02634 
02635     _expr = scsym._expr->clone();
02636 
02637     _type = scsym._type;
02638 
02639     return *this;
02640 }
02641 
02642 void
02643 SymbolicConstantSymbol::print(ostream & o) const
02644 {
02645     o << "[sym \"" << _tag << "\" (class SYMBOLIC_CONSTANT)";
02646 
02647     /// ...  the _type field
02648     o << ", type=" << (Type &) _type;
02649 
02650     /// ...  the _expr field
02651     o << ", expr=";
02652     if (_expr)
02653         o << *_expr;
02654     else
02655         o << "Null";
02656 
02657     /// ...  the _overflow field
02658     if (_overflow)
02659         o << ", overflow=" << *_overflow;
02660 
02661     o << "]";
02662 }
02663 
02664 void
02665 SymbolicConstantSymbol::exchange_convert( VDL &vdl )
02666 {
02667     Symbol::exchange_convert( vdl );
02668 
02669     BinRep *b = CASTAWAY(BinRep *) vdl.data_ref();
02670 
02671     Set<BinRep> & S = b->find_ref("symtab")->find_ref( name_ref() )->to_set();
02672 
02673     BinRep *br = new BinRep(new List<BinRep>);
02674     br->to_tuple().ins_last(new BinRep( "class" ));
02675     br->to_tuple().ins_last(new BinRep( "SYMBOLIC_CONSTANT" ));
02676     S.ins( br );
02677 
02678     if (expr_ref() != 0) {
02679         br = new BinRep(new List<BinRep>);
02680         br->to_tuple().ins_last( new BinRep( "expr" ));
02681         br->to_tuple().ins_last( new BinRep( expr_ref()->exchange_expr(vdl) ));
02682         S.ins( br );
02683     }
02684 }
02685 
02686 void
02687 SymbolicConstantSymbol::fill_in( const BinRep & binstr,
02688                                  ExprTable & exprs,
02689                          const Dictionary<VoidPtrDef> & NOTUSED(stmts),
02690                          const Dictionary<VoidPtrDef> & NOTUSED(commons),
02691                          const Dictionary<VoidPtrDef>& NOTUSED(equivalences) )
02692 {
02693     if (_overflow)
02694         delete _overflow;
02695 
02696     _overflow = 0;
02697 
02698     if (_expr)
02699         delete _expr;
02700 
02701     _expr = 0;
02702 
02703     String          type_declaration;
02704     int             size_declaration = 0;
02705     int             size_was_defaulted = 0;
02706 
02707     for (Iterator<BinRep> iter = binstr.to_set(); iter.valid(); ++iter) {
02708         String          field;
02709 
02710         iter.current()[0].to_string(field);
02711     
02712         if (field == "class") {
02713             String          class_type;
02714 
02715             iter.current()[1].to_string(class_type);
02716             p_assert(class_type == "SYMBOLIC_CONSTANT", "not a SYM_CONST");
02717         }
02718         else if (field == "data") {
02719             IntConstExpr   *iexpr = new IntConstExpr(0);
02720 
02721             iexpr->value(iter.current()[1].to_integer());
02722             _expr = iexpr;
02723         }
02724         else if (field == "expr") {
02725             int index = iter.current()[1].to_integer();
02726     
02727             _expr = exprs[index];
02728         }
02729         else if (field == "type") {
02730             /// ...  Save this field for later processing
02731             iter.current()[1].to_string(type_declaration);
02732         }
02733         else if (field == "size") {
02734             /// ...  Save this field for later processing
02735             size_declaration = _get_size(iter.current()[1], binstr);
02736         }
02737         else if (field == "sizedef") {
02738             size_was_defaulted = convert_true_false(iter.current()[1], binstr);
02739         }
02740         else {
02741             /// ...  Unrecognized -- add to overflow
02742 
02743             warn_overflow_map("SymbolicConstantSymbol", iter.current());
02744 
02745             if (!_overflow) {
02746                 _overflow = new BinRep;
02747                 Set<BinRep> *S = new Set<BinRep>;
02748                 _overflow->put_set( S );
02749             }
02750             _overflow->ins(iter.current());
02751         }
02752     }
02753 
02754     /// ...  Now process the _type field
02755 
02756     if (!type_declaration.defined()) {
02757         cerr << "Error: SymbolicConstantSymbol::SymbolicConstantSymbol: "
02758              << "No type was declared for binstr object: "
02759              << binstr << endl; 
02760 
02761         p_abort("(see above message)");
02762     }
02763 
02764     p_assert(_expr != 0,
02765              "Expression field is null after filling in a "
02766              "SymbolicConstantSymbol from a binstring -- perhaps the "
02767              "Polaris structure sent in contained an error");
02768 
02769     /// ...  Now check the type that was sent in
02770 
02771     Type            type;
02772 
02773     if (size_was_defaulted)
02774         type.set(type_declaration);
02775     else
02776         type.set(type_declaration, size_declaration);
02777 
02778     type.redimension(0);
02779     _type = type;
02780 
02781 ///     if (type != _expr->type()) {
02782 ///         cerr << "SymbolicConstantSymbol::fill_in():  "
02783 ///              << "The type information in the binstr was " << endl;
02784 ///         cerr << type << ", but the expression field's type was "
02785 ///              << _expr->type() << "." << endl;
02786 ///         cerr << "The type information in the expression field"
02787 ///              << " is being used and the other" << endl;
02788 ///         cerr << "ignored.  The expression field is:" << endl;
02789 ///         cerr << "    " << *_expr << endl << endl;
02790 ///     }
02791 
02792 }
02793 
02794 int
02795 SymbolicConstantSymbol::structures_OK() const
02796 {
02797     if (!Symbol::structures_OK())
02798         return 0;
02799 
02800     if (_expr == 0) {
02801         cerr << "SymbolicConstantSymbol::structures_OK(): "
02802              << "found a NULL _expr field.";
02803         cerr << "In context of SymbolicConstantSymbol:\n  " << flush
02804              << *this << endl;
02805         return 0;
02806     }
02807 
02808     CHECK_PTR_STRUCTURES(SymbolicConstantSymbol, _expr);
02809 
02810     return 1;
02811 }
02812 
02813 void
02814 SymbolicConstantSymbol::relink_dptrs(ProgramUnit & p)
02815 {
02816     if (_expr)
02817         _expr->relink_eptrs(p);
02818 }
02819 
02820 
02821 /// class BlockDataSymbol
02822 
02823 BlockDataSymbol &
02824 BlockDataSymbol::operator = (const BlockDataSymbol & other) 
02825 {
02826     _last_renaming_append = -1;
02827     _tag = other._tag;
02828 
02829     if (_overflow)
02830         delete _overflow;
02831 
02832     _overflow = ((other._overflow) ? new BinRep(*other._overflow) : 0);
02833 
02834     return *this;
02835 }
02836 
02837 Symbol         *
02838 BlockDataSymbol::clone() const
02839 {
02840     return new BlockDataSymbol(*this);
02841 }
02842 
02843 Symbol         *
02844 BlockDataSymbol::clone_all() const
02845 {
02846     return new BlockDataSymbol(*this);
02847 }
02848 
02849 
02850 BlockDataSymbol::~BlockDataSymbol()
02851 {
02852     /// ...  nothing to do
02853 }
02854 
02855 const Type &
02856 BlockDataSymbol::type() const
02857 {
02858     Type *undef_type = new Type(make_type(UNDEFINED_TYPE));
02859     return *undef_type;
02860 }
02861 
02862 void
02863 BlockDataSymbol::print(ostream & o) const
02864 {
02865     o << "[sym \"" << _tag << "\" (class BLOCKDATA)";
02866 
02867     /// ...  the _overflow field
02868     if (_overflow)
02869         o << ", overflow=" << *_overflow;
02870 
02871     o << "]";
02872 }
02873 
02874 void
02875 BlockDataSymbol::exchange_convert( VDL &vdl )
02876 {
02877     Symbol::exchange_convert( vdl );
02878 
02879     BinRep *b = CASTAWAY(BinRep *) vdl.data_ref();
02880 
02881     Set<BinRep> & S = b->find_ref("symtab")->find_ref( name_ref() )->to_set();
02882 
02883     BinRep *br = new BinRep(new List<BinRep>);
02884     br->to_tuple().ins_last(new BinRep( "class" ));
02885     br->to_tuple().ins_last(new BinRep( "BLOCK_DATA" ));
02886     S.ins( br );
02887 }
02888 
02889 void
02890 BlockDataSymbol::fill_in(const BinRep & binstr,
02891                          ExprTable & NOTUSED(exprs),
02892                          const Dictionary<VoidPtrDef>& NOTUSED(stmts),
02893                          const Dictionary<VoidPtrDef>& NOTUSED(commons),
02894                          const Dictionary<VoidPtrDef>& NOTUSED(equivalences))
02895 {
02896     if (_overflow)
02897         delete _overflow;
02898 
02899     _overflow = 0;
02900 
02901     for (Iterator<BinRep> iter = binstr.to_set(); iter.valid(); ++iter) {
02902         String          field;
02903 
02904         iter.current()[0].to_string(field);
02905 
02906         if (field == "class") {
02907             String          class_type;
02908     
02909             iter.current()[1].to_string(class_type);
02910 
02911             p_assert(class_type == "BLOCKDATA", "class is not BLOCKDATA");
02912         }
02913         else {
02914             /// ...  Unrecognized -- add to overflow
02915 
02916             warn_overflow_map("BlockDataSymbol", iter.current());
02917 
02918             if (!_overflow) {
02919                 _overflow = new BinRep;
02920                 Set<BinRep> *S = new Set<BinRep>;
02921                 _overflow->put_set( S );
02922             }
02923             _overflow->ins(iter.current());
02924         }
02925     }
02926 }
02927 
02928 int
02929 BlockDataSymbol::structures_OK() const
02930 {
02931     if (!Symbol::structures_OK())
02932         return 0;
02933 
02934     return 1;
02935 }
02936 
02937 void
02938 BlockDataSymbol::relink_dptrs(ProgramUnit & /* p */)
02939 {
02940 /// Nothing to do
02941 }
02942 
02943 
02944 /// class NamelistSymbol
02945 
02946 NamelistSymbol &
02947 NamelistSymbol::operator = (const NamelistSymbol & other) 
02948 {
02949     _last_renaming_append = -1;
02950     _tag = other._tag;
02951 
02952     if (_overflow)
02953         delete _overflow;
02954 
02955     _overflow = ((other._overflow) ? new BinRep(*other._overflow) : 0);
02956 
02957     return *this;
02958 }
02959 
02960 Symbol         *
02961 NamelistSymbol::clone() const
02962 {
02963     return new NamelistSymbol(*this);
02964 }
02965 
02966 Symbol         *
02967 NamelistSymbol::clone_all() const
02968 {
02969     return new NamelistSymbol(*this);
02970 }
02971 
02972 NamelistSymbol::~NamelistSymbol()
02973 {
02974     /// ...  nothing to do
02975 }
02976 
02977 const Type &
02978 NamelistSymbol::type() const
02979 {
02980     Type *undef_type = new Type(make_type(UNDEFINED_TYPE));
02981     return *undef_type;
02982 }
02983 
02984 void
02985 NamelistSymbol::print(ostream & o) const
02986 {
02987     o << "[sym \"" << _tag << "\" (class NAMELIST)";
02988 
02989     /// ...  the _overflow field
02990     if (_overflow)
02991         o << ", overflow=" << *_overflow;
02992 
02993     o << "]";
02994 }
02995 
02996 void
02997 NamelistSymbol::exchange_convert( VDL &vdl )
02998 {
02999     Symbol::exchange_convert( vdl );
03000 
03001     BinRep *b = CASTAWAY(BinRep *) vdl.data_ref();
03002 
03003     Set<BinRep> & S = b->find_ref("symtab")->find_ref( name_ref() )->to_set();
03004 
03005     BinRep *br = new BinRep(new List<BinRep>);
03006     br->to_tuple().ins_last(new BinRep( "class" ));
03007     br->to_tuple().ins_last(new BinRep( "NAMELIST" ));
03008     S.ins( br );
03009 }
03010 
03011 void
03012 NamelistSymbol::fill_in(const BinRep & binstr,
03013                         ExprTable & NOTUSED(exprs),
03014                         const Dictionary<VoidPtrDef>& NOTUSED(stmts),
03015                         const Dictionary<VoidPtrDef>& NOTUSED(commons),
03016                         const Dictionary<VoidPtrDef>& NOTUSED(equivalences))
03017 {
03018     if (_overflow)
03019         delete _overflow;
03020 
03021     _overflow = 0;
03022 
03023     for (Iterator<BinRep> iter = binstr.to_set(); iter.valid(); ++iter) {
03024         String          field;
03025 
03026         iter.current()[0].to_string(field);
03027 
03028         if (field == "class") {
03029             String          class_type;
03030     
03031             iter.current()[1].to_string(class_type);
03032             p_assert(class_type == "NAMELIST", "class is not NAMELIST");
03033         }
03034         else {
03035             /// ...  Unrecognized -- add to overflow
03036 
03037             warn_overflow_map("NamelistSymbol", iter.current());
03038 
03039             if (!_overflow) {
03040                 _overflow = new BinRep;
03041                 Set<BinRep> *S = new Set<BinRep>;
03042                 _overflow->put_set( S );
03043             }
03044             _overflow->ins(iter.current());
03045         }
03046     }
03047 }
03048 
03049 int
03050 NamelistSymbol::structures_OK() const
03051 {
03052     if (!Symbol::structures_OK())
03053         return 0;
03054 
03055     return 1;
03056 }
03057 
03058 void
03059 NamelistSymbol::relink_dptrs(ProgramUnit & /* p */)
03060 {
03061 /// Nothing to do
03062 }
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:06:14 2005