00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "c_breeze.h"
00039
00040
00041
00042
00043
00044
00045
00046
00047 bool Symbols::TrackScopeExits = false;
00048 bool Symbols::TrackInsertSymbol = false;
00049 bool Symbols::TrackIds = false;
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 template <class T>
00060 SymbolTable<T>::~SymbolTable()
00061 {
00062
00063
00064 for (table_p p = _table.begin() ; p != _table.end(); ++p)
00065 delete (*p);
00066 }
00067
00068
00069 template <class T>
00070 void SymbolTable<T>::mark_nodes (void) {
00071 for (table_p p = _table.begin() ; p != _table.end(); ++p) {
00072
00073 scope * sc = (*p);
00074
00075
00076
00077 for (scope_p s = sc->begin(); s != sc->end(); ++s) {
00078 Node *n = (Node *) ((*s).second);
00079 n->mark = true;
00080 }
00081 }
00082 }
00083
00084
00085
00086 template <class T>
00087 void SymbolTable<T>::reset()
00088 {
00089
00090
00091 for (table_p p = _table.begin() ; p != _table.end(); ++p) {
00092
00093 scope * sc = (*p);
00094
00095
00096
00097 for (scope_p s = sc->begin(); s != sc->end(); ++s)
00098 notify_exit_scope((*s).second);
00099
00100
00101
00102 delete sc;
00103 }
00104
00105 _table.clear();
00106 _table.push_front(new scope());
00107 }
00108
00109
00110
00111
00112
00113 template <class T>
00114 T SymbolTable<T>::insert(const string & name, T sym)
00115 {
00116 if (Symbols::TrackInsertSymbol)
00117 cerr << "InsertSymbol(" << name << ", " << ")" << endl;
00118
00119
00120 scope * sc = _table.front();
00121
00122
00123 scope_p s = sc->find(name);
00124
00125
00126
00127 if (s != sc->end())
00128 return (*s).second;
00129
00130
00131
00132 (*sc)[name] = sym;
00133
00134 return (T) 0;
00135 }
00136
00137
00138
00139 template <class T>
00140 T SymbolTable<T>::lookup(const string & name)
00141 {
00142 table_p p = _table.begin();
00143 bool found = false;
00144 scope * sc;
00145 scope_p s;
00146 T sym_out;
00147
00148 do {
00149 sc = (*p);
00150 s = sc->find(name);
00151 if (s != sc->end()) {
00152 found = true;
00153 p = _table.end();
00154 }
00155 else
00156 ++p;
00157 } while (! found && (p != _table.end()));
00158
00159 if (found)
00160 sym_out = (*s).second;
00161 else
00162 sym_out = (T) 0;
00163
00164 return sym_out;
00165 }
00166
00167
00168
00169 template <class T>
00170 void SymbolTable<T>::enter_scope()
00171 {
00172 if (_is_nested)
00173 _table. push_front(new scope());
00174 }
00175
00176
00177
00178 template <class T>
00179 void SymbolTable<T>::exit_scope()
00180 {
00181 if (_is_nested) {
00182
00183 scope * top = _table.front();
00184
00185 for (scope_p s = top->begin(); s != top->end(); ++s)
00186 notify_exit_scope((*s).second);
00187
00188 _table.pop_front();
00189 delete top;
00190 }
00191 }
00192
00193 template <class T>
00194 void SymbolTable<T>::print(FILE * out)
00195 {
00196 }
00197
00198 template <class T>
00199 string SymbolTable<T>::insert_unique(const string & root, T sym)
00200 {
00201 char buf[33];
00202 static unsigned counter = 0;
00203 T existing;
00204 string new_name;
00205
00206
00207
00208 existing = lookup( root );
00209 if (existing) {
00210
00211
00212
00213 do {
00214 sprintf(buf, "%.16s%d", root.c_str(), ++counter);
00215 string tmp(buf);
00216 existing = lookup( tmp );
00217 } while (existing != 0);
00218
00219 new_name = string(buf);
00220 }
00221 else
00222 new_name = root;
00223
00224
00225
00226 existing = insert(new_name, sym);
00227
00228 return new_name;
00229 }
00230
00231
00232
00233 bool Identifiers_table::is_a_type(const string & name)
00234 {
00235 declNode * var = lookup(name);
00236 if (var)
00237 return var->storage_class() == declNode::TYPEDEF;
00238
00239 return false;
00240 }
00241
00242
00243
00244
00245
00246 Identifiers_table::Identifiers_table()
00247 : SymbolTable< declNode * >(true)
00248 {}
00249
00250 Labels_table::Labels_table()
00251 : SymbolTable< labelNode * >(false)
00252 {}
00253
00254 Tags_table::Tags_table()
00255 : SymbolTable< suespecNode * >(true)
00256 {}
00257
00258 Externals_table::Externals_table()
00259 : SymbolTable< declNode * >(false)
00260 {}
00261
00262
00263
00264
00265
00266 void Identifiers_table::shadow(declNode * create, declNode * shadowed)
00267 {
00268
00269 if (create != shadowed && CBZ::WarningLevel == 5) {
00270 CBZ::Warning(5, create->coord(),
00271 string("`") + create->name() + string("' shadows previous declaration"));
00272 cerr << "\tPrevious declaration: " << shadowed->coord() << endl;
00273 }
00274 }
00275
00276 void Identifiers_table::notify_exit_scope(declNode * var)
00277 {
00278 typeNode * type = var->type();
00279 assert(type);
00280
00281 if (var->references() == 0 && type->typ() != Func) {
00282 if ((var->decl_location() == declNode::BLOCK) &&
00283 (var->storage_class() != declNode::EXTERN))
00284 CBZ::Warning(5, var->coord(), string("unused variable `") + var->name() + string("'"));
00285 }
00286 }
00287
00288 void Labels_table::shadow(labelNode * create, labelNode * shadowed)
00289 {
00290 }
00291
00292 void Labels_table::notify_exit_scope(labelNode * label)
00293 {
00294 if (label->is_undeclared())
00295 CBZ::SyntaxError(label->coord(),
00296 string("undefined label `") + label->name() + string("'"));
00297
00298 if (label->references().empty()) {
00299 if (label->coord().is_unknown() == false)
00300 CBZ::Warning(5, label->coord(), string("unreferenced label `") +
00301 label->name() + string("'"));
00302 }
00303 }
00304
00305 void Tags_table::shadow(suespecNode * create, suespecNode * shadowed)
00306 {
00307
00308 if (create != shadowed && CBZ::WarningLevel == 5) {
00309 CBZ::Warning(5, create->coord(),
00310 string("struct/union/enum tag `") + create->name() +
00311 string("' shadows previous declaration"));
00312 cerr << "\tPrevious declaration: " << shadowed->coord() << endl;
00313 }
00314 }
00315
00316 void Tags_table::notify_exit_scope(suespecNode * dead)
00317 {
00318 }
00319
00320 void Externals_table::shadow(declNode * create, declNode * shadowed)
00321 {
00322 }
00323
00324 void Externals_table::notify_exit_scope(declNode * var)
00325 {
00326 typeNode * type = var->type();
00327 assert(type);
00328
00329 if (var->references() == 0 && type->typ() != Func) {
00330 if ((var->decl_location() == declNode::BLOCK) &&
00331 (var->storage_class() != declNode::EXTERN))
00332 CBZ::Warning(5, var->coord(), string("unused variable `") + var->name() + string("'"));
00333 }
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 template class SymbolTable<declNode *>;
00374 template class SymbolTable<suespecNode *>;
00375 template class SymbolTable<labelNode *>;