00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef POLARIS_GNU_PRAGMAS
00018 #pragma implementation
00019 #endif
00020
00021 #include <ctype.h>
00022 #include <stdlib.h>
00023 #include <strstream.h>
00024
00025 #include "BinRep.h"
00026 #include "Boolean.h"
00027 #include "Collection/KeyIterator.h"
00028 #include "Collection/Map.h"
00029 #include "Declaration.h"
00030 #include "Expression/Expression.h"
00031 #include "Expression/IntrinsicTable.h"
00032 #include "IntElem.h"
00033 #include "String.h"
00034 #include "Symtab.h"
00035 #include "Symbol/FunctionSymbol.h"
00036 #include "Symbol/VariableSymbol.h"
00037 #include "VDL.h"
00038 #include "debug.h"
00039 #include "utilities/intrinsic_util.h"
00040 #include "utilities/string_util.h"
00041 #include "utilities/switches_util.h"
00042 #include "utilities/symbol_util.h"
00043 #include "Directive/Directive.h"
00044
00045 #include "macros.h"
00046 #include "p-assert.h"
00047
00048 template void relink_all_dptrs(Dictionary<Symbol> &,
00049 ProgramUnit &);
00050
00051 ostream &
00052 operator << (ostream & o, const Symtab & symtab)
00053 {
00054 o << "{\n";
00055
00056 DictionaryIter<Symbol> iter = (Dictionary<Symbol>&) symtab._dict;
00057
00058 while (iter.valid()) {
00059 cout << iter.current() << "\n";
00060 ++iter;
00061 }
00062
00063 o << "}\n";
00064
00065 return o;
00066 }
00067
00068 Symtab::Symtab(const BinRep & binstr)
00069 {
00070 #ifdef CLASS_INSTANCE_REGISTRY
00071 register_instance(SYMTAB, sizeof(Symtab), this);
00072 #endif
00073
00074 for (Iterator<BinRep> iter = binstr.to_set(); iter.valid(); ++iter) {
00075 String symbol_name;
00076
00077 iter.current()[0].to_string(symbol_name);
00078
00079 if (dbx_symtab_debug_level >= 1)
00080 cout << "Symtab: Initializing " << symbol_name << "\n";
00081
00082 const BinRep &bs = iter.current()[1];
00083 Symbol *sym = make_symbol(symbol_name, bs );
00084
00085 _dict.ins(sym);
00086 }
00087 }
00088
00089 Symtab::Symtab(const Symtab &s)
00090 {
00091 #ifdef CLASS_INSTANCE_REGISTRY
00092 register_instance(SYMTAB, sizeof(Symtab), this);
00093 #endif
00094
00095 Symtab::operator = (s);
00096 }
00097
00098 Symtab::~Symtab()
00099 {
00100 #ifdef CLASS_INSTANCE_REGISTRY
00101 unregister_instance(SYMTAB, this);
00102 #endif
00103 }
00104
00105 Symtab &
00106 Symtab::operator = (const Symtab &s)
00107 {
00108 _dict.clear();
00109
00110 for (DictionaryIter<Symbol> iter = s._dict; iter.valid(); ++iter)
00111 _dict.ins( iter.current().clone_all() );
00112
00113 return (*this);
00114 }
00115
00116 Symtab *
00117 Symtab::clone() const
00118 {
00119 return new Symtab( *this );
00120 }
00121
00122 void
00123 Symtab::fill_in(const BinRep & binstr, ExprTable & exprs,
00124 const Dictionary<VoidPtrDef> & stmts,
00125 const Dictionary<VoidPtrDef> & commons,
00126 const Dictionary<VoidPtrDef> & equivalences)
00127 {
00128 for (Iterator<BinRep> iter = binstr.to_set(); iter.valid(); ++iter) {
00129
00130
00131
00132 String symbol_name;
00133
00134 iter.current()[0].to_string(symbol_name);
00135
00136 if (dbx_symtab_debug_level >= 2)
00137 cout << "Symtab: Filling in " << symbol_name << "\n";
00138
00139
00140
00141 _dict[symbol_name].fill_in( iter.current()[1],
00142 exprs, stmts, commons, equivalences);
00143
00144 if (dbx_symtab_debug_level >= 3)
00145 cout << "..." << _dict[symbol_name] << "\n";
00146 }
00147 }
00148
00149
00150
00151 typedef Map<Symbol,IntElem> TopSortMap;
00152
00153 static int
00154 top_sort_expressions( TopSortMap &map, Expression &e )
00155 {
00156 if (e.op() == ID_OP)
00157 return (map.find_ref(e.symbol()) != 0 ? 1 : 0);
00158
00159 int count = 0;
00160
00161 for (Iterator<Expression> iter = e.arg_list(); iter.valid(); ++iter)
00162 count += top_sort_expressions( map, iter.current() );
00163
00164 return count;
00165 }
00166
00167 static void
00168 top_sort_parameters( TopSortMap &map )
00169 {
00170 for (KeyIterator<Symbol,IntElem> iter = map; iter.valid(); ++iter) {
00171 iter.current_data().value(
00172 top_sort_expressions( map, *iter.current_key().expr_ref() ));
00173 }
00174 }
00175
00176
00177 static int
00178 str_case_compare( const char* str1, const char* str2 )
00179 {
00180 int len = strlen(str2);
00181 if (strlen(str1) != len) return 1;
00182 else {
00183 char cbuf1[len+1];
00184 for (int i = 0; i <= len; str1++)
00185 cbuf1[i++] = (islower(*str1) ? toupper(*str1) : *str1);
00186 return strcmp(cbuf1, str2);
00187 }
00188 }
00189
00190
00191
00192 void
00193 Symtab::write(ostream & o,
00194 int space_for_label GIV(0),
00195 int max_line_len GIV(FORTRAN_MAX_LINE_LEN)) const
00196 {
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 TopSortMap param_map;
00207 Dictionary<Declaration> decl_dict;
00208
00209 DirectiveType output_language = (DirectiveType) switch_value("output_lang");
00210
00211
00212
00213 Declaration saved_decl("SAVE", " ", "",space_for_label, max_line_len);
00214 Declaration intr_decl("INTRINSIC", " ", "",space_for_label, max_line_len);
00215 Declaration extern_decl("EXTERNAL", " ", "",space_for_label, max_line_len);
00216 Declaration dim_decl("DIMENSION", " ", "",space_for_label, max_line_len);
00217 Declaration param_decl("PARAMETER", " (",")",space_for_label, max_line_len);
00218 Declaration global_decl("GLOBAL", " ", "",space_for_label, max_line_len);
00219 Declaration pointer_decl("POINTER", " ","",space_for_label, max_line_len);
00220 Declaration allocatable_decl("ALLOCATABLE", " ","",space_for_label, max_line_len);
00221
00222 for (const String *id = _dict.first_ref();
00223 id; id = _dict.successor_ref(*id)) {
00224 const Symbol &sym = *_dict.find_ref( *id );
00225 SYMBOL_CLASS sym_class = sym.sym_class();
00226
00227 if (output_language == DT_CEDAR_FORTRAN) {
00228
00229
00230
00231 if (sym_class == VARIABLE_CLASS && sym.global())
00232 global_decl << convert_case(sym.name_ref());
00233 }
00234
00235 if ((output_language == DT_CRAY_T3D) ||
00236 (output_language == DT_SGI) ||
00237 (output_language == DT_CONVEX_SPP) ||
00238 (output_language == DT_SGI_POWER) ||
00239 (output_language == DT_KAP_SGI)) {
00240
00241
00242
00243 if (sym_class == VARIABLE_CLASS && sym.is_pointer()) {
00244 ostrstream str;
00245
00246 str << "(" << convert_case(sym.name_ref()) << ",";
00247 str << convert_case(sym.assoc_variable().name_ref()) << ")";
00248 str << '\000';
00249
00250 char *data = str.str();
00251 pointer_decl << data;
00252 delete [] data;
00253 }
00254 }
00255
00256 if ((output_language == DT_CONVEX) ||
00257 (output_language == DT_CONVEX_SPP)) {
00258
00259
00260
00261 if (sym_class == VARIABLE_CLASS && sym.allocatable()) {
00262 allocatable_decl << convert_case(sym.name_ref());
00263 }
00264 }
00265
00266
00267
00268 if (sym_class == VARIABLE_CLASS && sym.saved())
00269 saved_decl << convert_case(sym.name_ref());
00270
00271
00272
00273 if (sym_class == SUBROUTINE_CLASS || sym_class == FUNCTION_CLASS) {
00274 if (sym.intrinsic())
00275
00276 intr_decl << convert_case(translate_special_name(sym.name_ref()));
00277
00278 if (sym.external()) {
00279 if ((output_language == DT_SGI) ||
00280 (output_language == DT_SGI_POWER) ||
00281 (output_language == DT_KAP_SGI)) {
00282 if ((strcmp(upcase_ch(sym.name_ref()),"MALLOC") != 0) &&
00283 (strcmp(upcase_ch(sym.name_ref()),"FREE") != 0)) {
00284 extern_decl << convert_case(sym.name_ref());
00285 }
00286 } else if (output_language == DT_CONVEX_SPP ){
00287 if ((strcmp(upcase_ch(sym.name_ref()),"SPPALLOC") != 0) &&
00288 (strcmp(upcase_ch(sym.name_ref()),"SPPFREE") != 0)) {
00289 extern_decl << convert_case(sym.name_ref());
00290 }
00291 } else {
00292 extern_decl << convert_case(sym.name_ref());
00293 }
00294 }
00295 }
00296
00297
00298
00299
00300 if (sym_class == VARIABLE_CLASS || sym_class == SYMBOLIC_CONSTANT_CLASS
00301 || (sym_class == FUNCTION_CLASS && sym.intrinsic() == False)) {
00302
00303 if (output_language != DT_CRAY_T3D ||
00304 (str_case_compare(sym.name_ref(), _T3D_NUM_PES) &&
00305 (sym_class != VARIABLE_CLASS || !sym.is_pointer()))) {
00306
00307 String type_name_str;
00308
00309 sym.type().format(type_name_str);
00310
00311 Declaration *decl = decl_dict.find_ref(type_name_str);
00312
00313 if (!decl) {
00314
00315
00316
00317 decl = new Declaration(type_name_str, " ", "",
00318 space_for_label, max_line_len);
00319 decl_dict.ins(decl);
00320 }
00321
00322 *decl << convert_case(sym.name_ref());
00323 }
00324 }
00325
00326
00327
00328 if (sym_class == VARIABLE_CLASS && sym.is_array()) {
00329 ostrstream str;
00330
00331 str << convert_case(sym.name_ref());
00332
00333 if (sym.allocatable()) {
00334 switch (output_language) {
00335 case DT_CEDAR_FORTRAN:
00336 case DT_CONVEX:
00337 case DT_CONVEX_SPP:
00338 sym.dim().print_all_colons(str);
00339 break;
00340 default:
00341 sym.dim().print(str);
00342 break;
00343 }
00344 }
00345 else {
00346 sym.dim().print(str);
00347 }
00348 str << '\000';
00349
00350 char *data = str.str();
00351 dim_decl << data;
00352 delete [] data;
00353 }
00354
00355
00356
00357 if (sym_class == SYMBOLIC_CONSTANT_CLASS)
00358 if (output_language != DT_CRAY_T3D ||
00359 str_case_compare(sym.name_ref(), _T3D_NUM_PES))
00360 param_map.ins(sym, new IntElem(0));
00361 }
00362
00363
00364
00365 o << saved_decl.str_ref();
00366 o << intr_decl.str_ref();
00367 o << extern_decl.str_ref();
00368
00369 if (output_language == DT_CEDAR_FORTRAN) {
00370
00371 o << global_decl.str_ref();
00372 }
00373
00374 if ((output_language == DT_CONVEX) ||
00375 (output_language == DT_CONVEX_SPP)) {
00376
00377 o << allocatable_decl.str_ref();
00378 }
00379
00380 for (const String *id1 = decl_dict.first_ref(); id1;
00381 id1 = decl_dict.successor_ref(*id1)) {
00382 Declaration *dec = decl_dict.find_ref( *id1 );
00383 o << dec->str_ref();
00384 }
00385
00386 if ((output_language == DT_CRAY_T3D) ||
00387 (output_language == DT_SGI) ||
00388 (output_language == DT_SGI_POWER) ||
00389 (output_language == DT_CONVEX_SPP) ||
00390 (output_language == DT_KAP_SGI)) {
00391
00392 o << pointer_decl.str_ref();
00393 }
00394
00395 while (param_map.entries() > 0) {
00396 Boolean infinite_loop = True;
00397
00398 top_sort_parameters( param_map );
00399
00400 for (KeyIterator<Symbol,IntElem> p_iter = param_map;
00401 p_iter.valid(); ++p_iter) {
00402 if (p_iter.current_data().value() == 0 ) {
00403 Symbol &sym = p_iter.current_key();
00404 ostrstream str;
00405
00406 str << convert_case(sym.name_ref()) << "=";
00407 str << *sym.expr_ref();
00408 str << '\000';
00409
00410 char *data = str.str();
00411 param_decl << data;
00412 delete [] data;
00413
00414 param_map.del( p_iter.current_key() );
00415 infinite_loop = False;
00416 }
00417 }
00418
00419 if (infinite_loop) {
00420 p_assert( False, "Symtab::write: parameters in a cycle" );
00421 break;
00422 }
00423 }
00424
00425 o << param_decl.str_ref();
00426 o << dim_decl.str_ref();
00427 }
00428
00429 Symtab::Symtab()
00430 {
00431 #ifdef CLASS_INSTANCE_REGISTRY
00432 register_instance(SYMTAB, sizeof(Symtab), this);
00433 #endif
00434 }
00435
00436 Symbol &
00437 Symtab::ins(Symbol * new_symbol)
00438 {
00439 p_assert(new_symbol != 0, "Symtab::ins(): symbol parameter is NULL");
00440
00441 _dict.ins(new_symbol, 0 );
00442 return *new_symbol;
00443 }
00444
00445 const Symbol *
00446 Symtab::find_ref(const char *symbol_name) const
00447 {
00448
00449
00450
00451
00452
00453 int i = 0;
00454 while (symbol_name[i] != 0) {
00455 p_assert(!islower(symbol_name[i]),
00456 "Symtab::find_ref: symbols must be upper case");
00457 i += 1;
00458 }
00459
00460 return _dict.find_ref(symbol_name);
00461 }
00462
00463 Symbol *
00464 Symtab::find_ref(const char *symbol_name)
00465 {
00466
00467
00468
00469
00470
00471 int i = 0;
00472 while (symbol_name[i] != 0) {
00473
00474
00475 if (islower(symbol_name[i]))
00476 p_abort( "Symtab::find_ref: symbols must be upper case" );
00477 i += 1;
00478 }
00479
00480 return _dict.find_ref(symbol_name);
00481 }
00482
00483 const Symbol &
00484 Symtab::operator[] (const char *symbol_name) const
00485 {
00486 const Symbol *sym = _dict.find_ref(symbol_name);
00487
00488 if (!sym) {
00489 cerr << "Error: Symtab: operator [ ]: Could not find symbol \""
00490 << symbol_name << "\" in symbol table.\n";
00491 p_assert(False, "ABORT");
00492 }
00493
00494 return *sym;
00495 }
00496
00497 Symbol &
00498 Symtab::operator[] (const char *symbol_name)
00499 {
00500 Symbol *sym = _dict.find_ref(symbol_name);
00501
00502 if (!sym) {
00503 cerr << "Error: Symtab: operator [ ]: Could not find symbol \""
00504 << symbol_name << "\" in symbol table.\n";
00505 p_assert(False, "ABORT");
00506 }
00507
00508 return *sym;
00509 }
00510
00511 void
00512 Symtab::del(const char *tag)
00513 {
00514 _dict.del(tag);
00515 }
00516
00517 int
00518 Symtab::entries() const
00519 {
00520 return _dict.entries();
00521 }
00522
00523 Symbol *
00524 Symtab::grab(const char *symbol_name)
00525 {
00526 return _dict.grab(symbol_name);
00527 }
00528
00529
00530 void
00531 Symtab::absorb(Symtab & other)
00532 {
00533 while (other._dict.entries()>0)
00534 rename_and_ins(other._dict.grab_arb());
00535 }
00536
00537
00538 Symbol &
00539 Symtab::rename_and_ins(Symbol * sym)
00540 {
00541 p_assert(sym != 0, "Symtab::rename_and_ins(): symbol parameter was NULL");
00542
00543 Symbol *already_exists = find_ref(sym->_tag);
00544
00545 if (((sym->sym_class() == FUNCTION_CLASS) ||
00546 (sym->sym_class() == SUBROUTINE_CLASS)) &&
00547 (sym->intrinsic() == IS_INTRINSIC)) {
00548 if (! already_exists)
00549 return ins(sym);
00550 return *already_exists;
00551 }
00552
00553 if (!already_exists && (lookup_intrinsic(sym->_tag) == False)) {
00554
00555 return ins(sym);
00556 }
00557 else {
00558
00559
00560 if (!already_exists)
00561 already_exists = sym;
00562
00563 String tag(sym->_tag);
00564 do {
00565 already_exists->renaming_suggestion(tag);
00566 } while (find_ref(tag) || (lookup_intrinsic(tag) == True));
00567 sym->_tag = tag;
00568
00569
00570
00571 return ins(sym);
00572 }
00573 }
00574
00575 int
00576 Symtab::structures_OK() const
00577 {
00578 if (!_dict.structures_OK()) {
00579 cerr << "In context of Symtab:\n" << flush;
00580 write(cout);
00581 return 0;
00582 }
00583
00584 return 1;
00585 }
00586
00587 DictionaryIter<Symbol>
00588 Symtab::iterator() const
00589 {
00590 return DictionaryIter<Symbol> (CASTAWAY(Dictionary<Symbol> &) _dict);
00591 }
00592
00593 Symbol &
00594 Symtab::ins_intrinsic(const char *name)
00595 {
00596 Symbol *s = find_ref( name );
00597
00598 if (s == 0) {
00599 String intrin = name;
00600 IntrinsicTable tab;
00601
00602 int index = tab.lookup_intrinsic( intrin );
00603 p_assert( index >= 0, "not an intrinsic function" );
00604
00605 s = new FunctionSymbol( intrin, tab.return_type(index),
00606 NOT_EXTERNAL, IS_INTRINSIC, NOT_FORMAL );
00607 this->ins( s );
00608 }
00609
00610 p_assert( s && s->intrinsic() == IS_INTRINSIC, "not an intrinsic" );
00611
00612 return *s;
00613 }
00614
00615
00616
00617
00618 void
00619 Symtab::relink_ptrs( ProgramUnit &p)
00620 {
00621 relink_all_dptrs( _dict, p );
00622
00623 }
00624
00625 void
00626 Symtab::exchange_convert( VDL &vdl )
00627 {
00628 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref();
00629
00630 if (b != 0) {
00631 List<BinRep> *L = new List<BinRep>;
00632 BinRep *bs;
00633
00634 bs = new BinRep( "symtab" );
00635 L->ins_last( bs );
00636
00637 bs = new BinRep( new Set<BinRep> );
00638 L->ins_last( bs );
00639
00640 BinRep *br = new BinRep( L );
00641 b->to_set().ins( br );
00642
00643 for (DictionaryIter<Symbol> iter = iterator(); iter.valid(); ++iter)
00644 iter.current().exchange_convert( vdl );
00645 }
00646 }