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 procNode * procNode::_current = (procNode *)0;
00043
00044
00045
00046
00047
00048 procNode::procNode(declNode * decl, blockNode * body, const Coord coord)
00049 : defNode(Proc, coord),
00050 _decl(decl),
00051 _body(body),
00052 _last_stack_local(0),
00053 _stack_frame_size(0),
00054 _return_label(NULL),
00055 _return_decl(NULL)
00056 {}
00057
00058
00059
00060
00061
00062
00063 extern char * cbtext;
00064
00065 procNode::procNode(bool old_style, declNode * decl_in)
00066 : defNode(Proc, decl_in->coord()),
00067 _decl(decl_in),
00068 _body(0),
00069 _last_stack_local(0),
00070 _stack_frame_size(0),
00071 _return_label(NULL),
00072 _return_decl(NULL)
00073 {
00074 assert(decl_in);
00075 declNode * the_decl = decl_in;
00076
00077 funcNode * func = (funcNode *) the_decl->type();
00078
00079 assert(func);
00080
00081 if (func->typ() != Func) {
00082 CBZ::SyntaxError(the_decl->coord(),
00083 string("expecting a function definition"));
00084 return;
00085 }
00086
00087
00088
00089
00090
00091 assert(*cbtext == '{');
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 the_decl->finish(the_decl->storage_class());
00104 the_decl->decl_location(declNode::PROC);
00105
00106
00107
00108
00109
00110
00111
00112
00113 _current = this;
00114
00115 if (func->args().empty()) {
00116
00117
00118
00119 declNode * void_decl = new declNode(new primNode(basic_type::Void, func->coord()), declNode::NONE);
00120 void_decl->decl_location(declNode::FORMAL);
00121
00122 func->args().push_front(void_decl);
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 }
00144
00145 if (old_style) {
00146
00147 declNode * var = the_decl;
00148
00149
00150
00151
00152 if (false) {
00153 decl_list & the_args = func->args();
00154 decl_list_p p;
00155 decl_list new_args;
00156
00157 for (p = the_args.begin(); p != the_args.end(); ++p) {
00158 if ((*p)->typ() == Id) {
00159 idNode * id = (idNode *) (*p);
00160
00161
00162 declNode * d = new declNode(id, declNode::NONE,
00163 new primNode(id->coord()),
00164 (exprNode *) 0, (exprNode *) 0);
00165 d->decl_location(declNode::FORMAL);
00166 new_args.push_back(d);
00167 }
00168 else
00169 new_args.push_back(*p);
00170
00171 }
00172
00173
00174
00175 func->args().swap(new_args);
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 }
00203
00204
00205
00206 CBZ::current_unit->enter_scope();
00207
00208
00209
00210 decl_list & the_args = func->args();
00211 decl_list_p p;
00212
00213 bool first = true;
00214 for (p = the_args.begin(); p != the_args.end(); ++p) {
00215
00216 if ((*p)->datatype()->is_ellipsis())
00217 ;
00218 else
00219 if ((*p)->datatype()->is_void()) {
00220 if (! first)
00221 CBZ::SyntaxError((*p)->coord(),
00222 string("void argument must be first"));
00223 }
00224 else
00225 if ((*p)->typ() == Decl) {
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 } else
00240 CBZ::SyntaxError((*p)->coord(),
00241 string("argument without a name"));
00242
00243 first = false;
00244 }
00245 }
00246
00247
00248
00249
00250
00251 void procNode::define(blockNode * the_body)
00252 {
00253 assert(decl());
00254
00255 CBZ::current_unit->exit_scope();
00256
00257 body(the_body);
00258
00259 if (! the_body) {
00260 CBZ::Warning(4, decl()->coord(),
00261 string("procedure `") + decl()->name() +
00262 string("' has no code"));
00263 } else {
00264
00265
00266
00267
00268 }
00269
00270 _current = 0;
00271 }
00272
00273 procNode * procNode::define_and(blockNode * the_body)
00274 {
00275 define(the_body);
00276 return this;
00277 }
00278
00279
00280
00281
00282
00283 basicblockNode * procNode::entry() const
00284 {
00285 return (basicblockNode *) _body->stmts().front();
00286 }
00287
00288 basicblockNode * procNode::exit() const
00289 {
00290 return (basicblockNode *) _body->stmts().back();
00291 }
00292
00293
00294
00295
00296
00297 typeNode * procNode::base_type(bool TdefIndir) const
00298 {
00299 return decl()->base_type(TdefIndir);
00300 }
00301
00302
00303
00304
00305
00306 void procNode::visit(Visitor * the_visitor)
00307 {
00308 the_visitor->at_proc(this);
00309 }
00310
00311 void procNode::walk(Walker & the_walker)
00312 {
00313 Walker::Order ord = the_walker.order();
00314
00315 if (ord == Walker::Preorder || ord == Walker::Both)
00316 the_walker.at_proc(this, Walker::Preorder);
00317
00318 if (the_walker.depth() == Walker::Subtree) {
00319
00320
00321 list_walker(pragmas(), the_walker);
00322
00323 if (decl())
00324 decl()->walk(the_walker);
00325
00326 if (body())
00327 body()->walk(the_walker);
00328 }
00329
00330 if (ord == Walker::Postorder || ord == Walker::Both)
00331 the_walker.at_proc(this, Walker::Postorder);
00332 }
00333
00334
00335
00336
00337
00338 void procNode::dataflow(FlowVal * v, FlowProblem & fp)
00339 {
00340 if (fp.forward()) {
00341 fp.flow_proc(v, this, FlowProblem::Entry);
00342
00343 if (body())
00344 body()->dataflow(v, fp);
00345
00346 v->meet(at_exit());
00347
00348 fp.flow_proc(v, this, FlowProblem::Exit);
00349 }
00350 else {
00351 fp.flow_proc(v, this, FlowProblem::Exit);
00352
00353 v->meet(at_exit());
00354
00355 if (body())
00356 body()->dataflow(v, fp);
00357
00358 fp.flow_proc(v, this, FlowProblem::Entry);
00359 }
00360 }
00361
00362
00363
00364
00365
00366 void procNode::output(output_context & ct, Node * parent)
00367 {
00368 decl()->output(ct, this);
00369
00370 if (body())
00371 body()->output(ct, this);
00372 else
00373 ct << '{' << '}';
00374 }
00375
00376
00377
00378
00379
00380
00381 Node * procNode::change(Changer & the_changer, bool redispatch)
00382 {
00383 Changer::Order ord = the_changer.order();
00384 procNode * the_proc = this;
00385
00386 if ((ord == Changer::Preorder || ord == Changer::Both) && ! redispatch)
00387 the_proc = (procNode *) the_changer.at_proc(the_proc, Changer::Preorder);
00388
00389 if (the_proc) {
00390
00391 if (the_proc != this)
00392 return the_proc->change(the_changer, true);
00393
00394 change_list(the_proc->pragmas(), the_changer);
00395
00396 declNode * old_decl = the_proc->decl();
00397 if (old_decl) {
00398 declNode * new_decl = (declNode *) old_decl->change(the_changer);
00399 if (old_decl != new_decl) {
00400
00401
00402 the_proc->decl(new_decl);
00403 }
00404 }
00405
00406 blockNode * old_body = the_proc->body();
00407 if (old_body) {
00408 blockNode * new_body = (blockNode *) old_body->change(the_changer);
00409 if (old_body != new_body) {
00410
00411
00412 the_proc->body(new_body);
00413 }
00414 }
00415
00416 }
00417
00418 if ((ord == Changer::Postorder || ord == Changer::Both) && ! redispatch)
00419 the_proc = (procNode *) the_changer.at_proc(the_proc, Changer::Postorder);
00420
00421 return the_proc;
00422 }
00423
00424
00425
00426
00427
00428 void procNode::set_initial_stack_local_offset( int offset )
00429 {
00430
00431 _last_stack_local = offset;
00432 }
00433
00434 int procNode::alloc_stack_local( declNode * decl ) {
00435
00436 if ( ! CBZ::ArchInfo.is_valid() ) {
00437 CBZFAIL(("Can't allocate stack space for declaration - missing "
00438 "architecture info. Specify with -arch."));
00439 }
00440
00441 declNode::Storage_location & loc = decl->storage_location();
00442
00443
00444 if ( loc._type == declNode::Storage_location::storageloc_stack )
00445 return loc._stack_offset;
00446
00447
00448 int size = decl->type()->alloc_size();
00449 assert( size > 0 );
00450 int align = decl->type()->alloc_align();
00451 assert( align > 0 );
00452
00453
00454 _last_stack_local = (( (_last_stack_local - size) - align + 1 )
00455 / align ) * align;
00456 loc._type = declNode::Storage_location::storageloc_stack;
00457 loc._stack_offset = _last_stack_local;
00458
00459
00460 return _last_stack_local;
00461 }
00462
00463
00464
00465
00466
00467 procNode::~procNode()
00468 {
00469
00470
00471 }
00472