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
00039
00040 #include "c_breeze.h"
00041 #include "linker.h"
00042 #include "ref_clone_changer.h"
00043
00044 bool Linker::debug = false;
00045
00046 Linker::Linker()
00047 : Walker(Preorder, Subtree),
00048 _external_symbols(),
00049 _internal_symbols(),
00050 _procedure_declarations(),
00051 _synthetic(),
00052 current_unit(0)
00053 {}
00054
00055 Linker::~Linker()
00056 {
00057 clear();
00058 }
00059
00060 void Linker::clear()
00061 {
00062
00063
00064 _external_symbols.clear();
00065 _internal_symbols.clear();
00066 _procedure_declarations.clear();
00067
00068
00069
00070 for (decl_name_map_p p = _synthetic.begin();
00071 p != _synthetic.end();
00072 ++p)
00073 {
00074 declNode * synth = (*p).second;
00075 _synthetic[synth->name()] = synth;
00076 _external_symbols[synth->name()] = synth;
00077 }
00078
00079 current_unit = 0;
00080 }
00081
00082 void Linker::link()
00083 {
00084
00085
00086
00087 clear();
00088
00089
00090
00091
00092 if (debug)
00093 cout << "Linker: first pass, collect external and internal symbols" << endl;
00094
00095 for (unit_list_p up = CBZ::Program.begin();
00096 up != CBZ::Program.end();
00097 ++up)
00098 {
00099 unitNode * unit = (*up);
00100 def_list & ds = unit->defs();
00101
00102
00103
00104
00105 for (def_list_p p = ds.begin();
00106 p != ds.end();
00107 ++p) {
00108 defNode * d = (*p);
00109 procNode * proc = 0;
00110 declNode * decl = 0;
00111
00112 if (d->typ() == Proc) {
00113 proc = (procNode *) d;
00114 decl = proc->decl();
00115 if (decl->decl_location() == declNode::PROC)
00116 _procedure_declarations[decl] = proc;
00117 }
00118
00119 if (d->typ() == Decl)
00120 decl = (declNode *)d;
00121
00122 if (decl) {
00123 if (decl->storage_class() == declNode::STATIC) {
00124 _internal_symbols[unit][decl->name()] = decl;
00125 if (debug)
00126 cout << " " << decl->name() << " at " << decl->coord() <<
00127 " : internal to " << unit->input_file() << endl;
00128 }
00129 else {
00130
00131
00132
00133
00134
00135 bool is_procedure_definition = (decl->decl_location() == declNode::PROC);
00136 bool is_toplevel_var = (decl->storage_class() == declNode::NONE) &&
00137 (decl->decl_location() == declNode::TOP) && (decl->type()->typ() != Func);
00138
00139 if (is_procedure_definition || is_toplevel_var) {
00140 _external_symbols[decl->name()] = decl;
00141 if (debug)
00142 cout << " " << decl->name() << " at " << decl->coord() <<
00143 " : extern -- declared in " << unit->input_file() << endl;
00144 }
00145 }
00146 }
00147
00148 }
00149
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159 if (debug)
00160 cout << "Linker: second pass, find externals with no definition:" << endl;
00161
00162 for (unit_list_p up = CBZ::Program.begin();
00163 up != CBZ::Program.end();
00164 ++up)
00165 {
00166 unitNode * unit = (*up);
00167 def_list & ds = unit->defs();
00168
00169
00170
00171 for (def_list_p p = ds.begin();
00172 p != ds.end();
00173 ++p) {
00174 defNode * d = (*p);
00175
00176
00177
00178 if (d->typ() == Decl) {
00179 declNode * decl = (declNode *)d;
00180
00181
00182
00183 if ((decl->storage_class() == declNode::EXTERN) ||
00184 (decl->type()->typ() == Func)) {
00185
00186
00187
00188 bool unused;
00189 if ( ! lookup_symbol(unit, decl->name(), unused)) {
00190
00191
00192
00193 create_synthetic(decl);
00194
00195 if (debug)
00196 cout << " " << decl->name() << " is synthetic." << endl;
00197 }
00198 }
00199 }
00200
00201 }
00202
00203 }
00204
00205
00206
00207
00208 if (debug)
00209 cout << "Linker: third pass, fix idNode declarations:" << endl;
00210
00211 for (unit_list_p up = CBZ::Program.begin();
00212 up != CBZ::Program.end();
00213 ++up)
00214 {
00215 unitNode * unit = (*up);
00216 current_unit = unit;
00217 unit->walk(*this);
00218 }
00219 }
00220
00223 declNode * Linker::lookup_symbol(unitNode * current, string name,
00224 bool & is_synthetic_decl)
00225 {
00226
00227
00228 is_synthetic_decl = (_synthetic.find(name) != _synthetic.end());
00229
00230
00231
00232 decl_name_map & current_unit_internals = _internal_symbols[current];
00233 decl_name_map_p p = current_unit_internals.find(name);
00234 if (p == current_unit_internals.end()) {
00235
00236
00237
00238 p = _external_symbols.find(name);
00239 if (p == _external_symbols.end())
00240 {
00241
00242 return 0;
00243 }
00244 }
00245
00246 return (*p).second;
00247 }
00248
00251 procNode * Linker::lookup_procedure(declNode * decl)
00252 {
00253
00254
00255 if (decl) {
00256 proc_decl_map_p p = _procedure_declarations.find(decl);
00257 if (p != _procedure_declarations.end())
00258 return (*p).second;
00259 }
00260
00261 return 0;
00262 }
00263
00264 bool Linker::create_synthetic(declNode * local_decl)
00265 {
00266 decl_name_map_p p = _synthetic.find(local_decl->name());
00267 if (p != _synthetic.end()) {
00268 cerr << "Linker error: external variable \"" << local_decl->name() <<
00269 "\" has duplicate definitions." << endl;
00270 return false;
00271 }
00272 else {
00273 declNode * decl = (declNode *) ref_clone_changer::clone(local_decl, false);
00274 _synthetic[local_decl->name()] = decl;
00275 _external_symbols[decl->name()] = decl;
00276 return true;
00277 }
00278 }
00279
00280
00281
00282
00283 void Linker::at_id(idNode * the_id, Order ord)
00284 {
00285 declNode * decl = the_id->decl();
00286 bool lookup = false;
00287
00288
00289
00290
00291
00292
00293 if (decl) {
00294 if ((decl->decl_location() == declNode::TOP) ||
00295 (decl->decl_location() == declNode::PROC) ||
00296 (decl->decl_location() == declNode::UNKNOWN))
00297 lookup = true;
00298
00299 if (decl->type() && (decl->type()->typ() == Func))
00300 lookup = true;
00301 }
00302 else
00303 lookup = true;
00304
00305 if (lookup) {
00306
00307
00308
00309
00310 bool is_synthetic_decl;
00311 declNode * real_decl = lookup_symbol(current_unit, the_id->name(), is_synthetic_decl);
00312 the_id->decl(real_decl);
00313
00314 if (debug) {
00315 cout << " " << the_id->name() << " at " << the_id->coord();
00316 if (real_decl)
00317 cout << " : actual declaration at " << real_decl->coord() << endl;
00318 else
00319 cout << " : no declaration found." << endl;
00320 }
00321 }
00322 }
00323
00329 void Linker::at_call(callNode * the_call, Order ord)
00330 {
00331 if (the_call->name()->typ() == Id) {
00332 idNode * the_id = (idNode *) the_call->name();
00333
00334 process_call(the_id, the_call);
00335 }
00336 }
00337
00338
00343 void
00344 Linker::at_threeAddr(threeAddrNode * ta, Order ord)
00345 {
00351
00352 if (ta->op() && ta->op()->id()==Operator::FUNC_CALL)
00353 {
00354 operandNode * o = (operandNode *) ta->rhs1();
00355 assert(o);
00356 indexNode * i = o->var();
00357
00358 assert(i->typ()==Id);
00359 idNode * call = (idNode *)i;
00360
00361 bool is_func_ptr = o->star() || !o->fields().empty() || o->index() ||
00362 call->decl()->type()->follow_tdefs()->typ() == Ptr;
00363
00364 if(! is_func_ptr)
00365 process_call(call, NULL);
00366 }
00367 }
00368
00373 void
00374 Linker::process_call(idNode * call, callNode * callnode)
00375 {
00376 bool unused;
00377 declNode * real_decl = lookup_symbol(current_unit, call->name(), unused);
00378
00379 if (! real_decl) {
00380
00381
00382
00383
00384 declNode * decl = call->decl();
00385 create_synthetic(decl);
00386
00387 if (debug)
00388 cout << " " << decl->name() << " is a synthetic, old-style function." << endl;
00389 }
00390 else if(callnode)
00391 {
00392
00393
00394
00395 callnode->proc(lookup_procedure(real_decl));
00396 }
00397 }
00398
00399 proc_decl_map & Linker::procedure_declarations()
00400 {
00401 return _procedure_declarations;
00402 }
00403