ss_ss2pi_base.cc

Go to the documentation of this file.
00001 /*
00002    The lestes compiler suite
00003    Copyright (C) 2002, 2003, 2004, 2005 Miroslav Tichy
00004    Copyright (C) 2002, 2003, 2004, 2005 Petr Zika
00005    Copyright (C) 2002, 2003, 2004, 2005 Vojtech Hala
00006    Copyright (C) 2002, 2003, 2004, 2005 Jiri Kosina
00007    Copyright (C) 2002, 2003, 2004, 2005 Pavel Sanda
00008    Copyright (C) 2002, 2003, 2004, 2005 Jan Zouhar
00009    Copyright (C) 2002, 2003, 2004, 2005 Rudolf Thomas
00010 
00011    This program is free software; you can redistribute it and/or modify
00012    it under the terms of the GNU General Public License as published by
00013    the Free Software Foundation; version 2 of the License.
00014 
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019 
00020    See the full text of the GNU General Public License version 2, and
00021    the limitations in the file doc/LICENSE.
00022 
00023    By accepting the license the licensee waives any and all claims
00024    against the copyright holder(s) related in whole or in part to the
00025    work, its use, and/or the inability to use it.
00026  
00027  */
00028 #include <algorithm>
00029 #include <iostream>
00030 #include <lestes/std/list.hh>
00031 #include <lestes/std/pair.hh>
00032 #include <lestes/std/reflect.hh>
00033 #include <lestes/msg/logger.hh>
00034 #include <lestes/msg/logger_util.hh>
00035 
00036 #include <lestes/backend_v2/interface/backend_data_builder.g.hh>
00037 #include <lestes/md/mem/mem_alloc_manager.g.hh>
00038 #include <lestes/md/types/copy_constructor_call_generator.g.hh>
00039 #include <lestes/md/functions/function_parameter_accessor.g.hh>
00040 #include <lestes/md/literals/literal_loader.g.hh>
00041 #include <lestes/md/literals/literal_info.g.hh>
00042 #include <lestes/md/mem/memory_allocator_bases.g.hh>
00043 #include <lestes/md/types/tm_data_type_base.g.hh>
00044 #include <lestes/md/registers/tm_register_base.g.hh>
00045 #include <lestes/md/types/ss_type2tm_type_convertor.g.hh>
00046 #include <lestes/backend_v2/intercode/pi_mem_factory.g.hh>
00047 
00048 #include <lestes/lang/cplus/sem/ss_type.g.hh>
00049 #include <lestes/lang/cplus/sem/ss_misc.g.hh>
00050 #include <lestes/lang/cplus/sem/ss_expr_binary_op.g.hh>
00051 #include <lestes/lang/cplus/sem/ss_expr_unary_op.g.hh>
00052 #include <lestes/lang/cplus/sem/ss_expr_funcall.g.hh>
00053 #include <lestes/lang/cplus/sem/ss_declaration.g.hh>
00054 #include <lestes/lang/cplus/sem/ss_type_builtin.g.hh>
00055 
00056 #include <lestes/lang/cplus/sem/ss_finders.g.hh>
00057 #include <lestes/lang/cplus/sem/ss_ss2pi_base.g.hh>
00058 #include <lestes/lang/cplus/sem/ss_ss2pi_typedefs.hh>
00059 #include <lestes/lang/cplus/sem/ss_literal_info.g.hh>
00060 #include <lestes/lang/cplus/sem/ss_type2info.g.hh>
00061 #include <lestes/lang/cplus/sem/ss_ss2pi_typedefs.hh>
00062 #include <lestes/lang/cplus/sem/sem.hh>
00063 
00064 
00065 package(lestes);
00066 package(lang);
00067 package(cplus);
00068 package(sem);
00069 
00070 using ::std::cerr;
00071 using ::std::max;
00072 using namespace ::lestes::std;
00073 using namespace ::lestes::msg;
00074 using namespace ::lestes::backend_v2::intercode;
00075 using namespace ::lestes::backend_v2::interface;
00076 using namespace ::lestes::backend_v2::structs;
00077 using namespace ::lestes::md::types;
00078 using namespace ::lestes::md::mem;
00079 using namespace ::lestes::md::registers;
00080 using namespace ::lestes::md::literals;
00081 using namespace ::lestes::md::functions;
00082 
00083 
00084 ////////////////////////////////////            Loggers & dumps                 //////////////////////////////
00085 
00086 
00087 declare_logger(dtl);    //destructor tables control
00088 declare_logger(fll);    //floating control
00089 declare_logger(spl);    //sequence points control
00090 declare_logger(gnl);    //general ss2pi logger
00091 
00092 initialize_logger( dtl, "destr_tab", sem_logger );
00093 initialize_logger( fll, "flow", sem_logger );
00094 initialize_logger( spl, "SP", sem_logger );
00095 initialize_logger( gnl, "ss2pi", sem_logger );
00096 
00097 //#define log_flow_indent "  "
00098 #define log_flow_indent "  "
00099 int log_count = 0;
00100 int log_indent(ptr< ::lestes::msg::logger > flow,int ind){      //indentation for control_flow logs
00101         for (int i=0; i<ind; i++){
00102                 flow << log_flow_indent;
00103         }
00104         return ind;
00105 }
00106 
00107 //#define plog(x) llog(x)
00108 //#define plog(x) llog_plain(x)
00109 #define plog
00110 
00111 //#define entry(a) plog(fll) << "       in  " << x->uid_get() << " (" << x->reflection_get()->back()->name_get() << ")\n" << eolog
00112 #define entry(a) log_indent(fll,log_count++), plog(fll) <<"       in  " << x->uid_get() << " (" << a << ")\n" << eolog
00113 #define outry(a) log_indent(fll,--log_count), plog(fll) <<"       out " << x->uid_get() << " (" << a << ")\n" << eolog
00114 
00115 /*!
00116   Dumps objects hierarchy starting from dumpable x.
00117 */
00118 void dump( ptr< object >x){
00119 plog(gnl)<<"..dumping..\n";
00120         ::std::ofstream f("dump.xml");
00121 	::lestes::std::dumper::dump(f,x);
00122         f.close();
00123 }
00124 
00125 /*!
00126   Dumps objects hierarchy starting from dumpable x.
00127 */
00128 void dumb( ptr< object >x){
00129 plog(gnl)<<"..dumbing..\n";
00130         ::std::ofstream f("dumb.xml");
00131 	::lestes::std::dumper::dump(f,x);
00132         f.close();
00133 }
00134 
00135 /*!
00136   Dumps objects hierarchy starting from dumpable x.
00137   Usage a=func(b,dung(c),d);
00138 */
00139 template <typename X> 
00140 ptr<X> dung( ptr< X >x){
00141 plog(gnl)<<"..dumbing..\n";
00142         ::std::ofstream f("dumb.xml");
00143 	::lestes::std::dumper::dump(f,x);
00144         f.close();
00145         return x;
00146 }
00147 
00148 
00149 /*!
00150   Print out top_level sequence points. For debuging purposes.
00151 */
00152 void summary_seq_points(ptr< ss_sp > x){
00153  {
00154         while (x->psp_get()) x=x->psp_get();
00155         ptr< ss_sp > tmp, tmp2;
00156         
00157         for (tmp=x; tmp->nsp_get(); tmp=tmp->nsp_get()){
00158                 plog(spl)<<tmp->uid_get()<<"->";
00159         }
00160         plog(spl)<<tmp->uid_get()<<"\n";
00161         
00162         for (tmp2=tmp; tmp2->psp_get(); tmp2=tmp2->psp_get()){
00163                 plog(spl)<<tmp2->uid_get()<<"->";
00164         }
00165         plog(spl)<<tmp2->uid_get()<<"\n";
00166  }
00167  {
00168         ptr< pi_pi >X = ss_sp2pi_sp(x);
00169         ptr< pi_pi > tmp, tmp2;
00170         
00171         for (tmp=X; tmp->nsp_get(); tmp=tmp->nsp_get()){
00172                 plog(spl)<<tmp->uid_get()<<"->";
00173         }
00174         plog(spl)<<tmp->uid_get()<<"\n";
00175         
00176         for (tmp2=tmp; tmp2->psp_get(); tmp2=tmp2->psp_get()){
00177                 plog(spl)<<tmp2->uid_get()<<"->";
00178         }
00179         plog(spl)<<tmp2->uid_get()<<"\n"<<eolog;
00180  }
00181 }
00182 
00183 
00184 ///////////////////////////////                 Common functions        ///////////////////////////////////
00185 
00186 
00187 /*!
00188   Main entry point for ss2pi transformation.
00189 */
00190 void ss2pi_start(ptr< ss_translation_unit > x){entry("start");
00191 
00192         //      dumb(x);        //To mantain constant numbers for structures in dumps
00193               
00194         ptr< variable_map_type > namespace_variable_map = variable_map_type::create();  //namespace-scope map
00195         
00196         ptr< ss_stmt2pi > stmt_visitor =                        //new visitor - new destructor list has to be created
00197                 ss_stmt2pi::create( NULL, NULL, namespace_variable_map );
00198         
00199         x->global_scope_get()->compound_stmt_get()->accept_ss_statement_visitor(stmt_visitor);
00200         
00201 outry("start");
00202 }
00203 
00204 /*!
00205   Converts returned result from expression visitor for requested type.
00206   TODO: reformulate dncast via visitors on pi_operand structures
00207 */
00208 ptr< pi_mem >pi_operand2pi_mem(ptr< pi_operand > x){
00209         
00210         ptr<pi_mem>p = x.dncast<pi_mem>();
00211         return p;
00212 }
00213 
00214 /*!
00215   Converts returned result from expression visitor for requested type.
00216   TODO: reformulate dncast via visitors on pi_operand structures
00217 */
00218 ptr< pi_mem_ptr_deref >pi_operand2pi_mem_pointer(ptr< pi_operand > x){
00219         
00220         ptr<pi_mem_ptr_deref>p = x.dncast<pi_mem_ptr_deref>();
00221         return p;
00222 }
00223 
00224 /*!
00225   Converts returned result from expression visitor for requested type.
00226   TODO: reformulate dncast via visitors on pi_operand structures
00227 */
00228 ptr< pi_preg >pi_operand2pi_preg(ptr< pi_operand > x){
00229 
00230         ptr<pi_preg>p = x.dncast<pi_preg>();
00231         return p;
00232 }
00233 
00234 
00235 /*!
00236   Computation of origin to get an apropriate pi_mem for pi_mem_factory.
00237   Premise for right construction: 1 side effect dont interfere(value change, volatile access)
00238         with more than one entity.
00239         
00240   Arguments:
00241         xsp points to sequence potin wherefrom we start our search (usually psp of current expression).
00242         
00243   Used variables:
00244         psp points to start of fullexpression, where wee look for previous side effects
00245 */
00246 ptr< pi_pi > ss_expr2pi::compute_origin(ptr< pi_mem_factory > x, ptr< ss_sp > xsp){
00247 
00248         for ( ptr< ss_sp > i=xsp; i!=psp ; i=i->psp_get()){                     //or all seq.points only inside fullexpression
00249         
00250                 list <srp <ss_se> >::iterator ise = i->pse_get()->begin();      //search for sideeffect, which interfere with given pi_mem_factory
00251                 for ( ; ise!=i->pse_get()->end(); ise++){
00252                         ptr< ss_expr2destination > dest_visitor = ss_expr2destination::create();
00253                         ptr< ss_expression > dest = dest_visitor->get_destination((*ise)->from_get());
00254                         
00255                         if (dest) {                                             // if side effect with destination
00256                         
00257                                 ptr< pi_mem > accessed;         //memory placeholder accessed by side effect
00258                                 
00259                                 expression_results_map_type::iterator expr_result = expr2operand_map->find(dest);       //get result of evaluation
00260                                 
00261                                 if ( expr_result == expr2operand_map->end() )           //this expression has not been evaluated yet
00262                                         accessed = this->returns_mem(dest);                     //evaluate it now
00263                                   else
00264                                          accessed = pi_operand2pi_mem( (*expr_result).second ); 
00265                                          
00266                                 if (accessed->factory_get() == x){              //we found side effect, where we accessed given x
00267                                         return accessed->origin_get();
00268                                 }//if acc
00269                         }//if dest
00270                 }//for se
00271         }//for psp
00272         
00273         return ss_sp2pi_sp(psp); // When no side effect inside fullexpression found, return sequence point on the begining of fullexpression
00274 }
00275 
00276 /*!
00277   Returning value from transforming expression visitor.
00278 */
00279 ptr< ::lestes::backend_v2::intercode::pi_preg > ss_expr2pi::returns_preg(const ptr < ss_expression > & o){
00280         ptr <pi_operand> res=this->returns(o);
00281         return pi_operand2pi_preg(res);
00282 }
00283 
00284 /*!
00285   Returning value from transforming expression visitor.
00286 */
00287 ptr< ::lestes::backend_v2::intercode::pi_mem > ss_expr2pi::returns_mem(const ptr < ss_expression > & o){
00288         ptr <pi_operand> res=this->returns(o);
00289         return pi_operand2pi_mem(res);
00290 }
00291 
00292 /*!
00293   Returning value from transforming expression visitor.
00294 */
00295 ptr< ::lestes::backend_v2::intercode::pi_mem_ptr_deref > ss_expr2pi::returns_mem_pointer(const ptr < ss_expression > & o){
00296         ptr <pi_operand> res=this->returns(o);
00297         return pi_operand2pi_mem_pointer(res);
00298 }
00299         
00300 
00301 /*
00302   Function for recursive building of pi_sp from ss_sp.
00303   The whole transformation of sequence points is lazy in the sense, that we transform only
00304   sequence points, which are available through psp and nsp.
00305   Stop mark for sequence points in ss as well as in pi layer is NULL.
00306   TODO: reformulate via maps, without ss_sp.pi_sp field.
00307 */
00308 ptr< pi_sp > ss_sp2pi_sp(ptr < ss_sp > sp){
00309         
00310         if (sp->pi_spe_get()) return sp->pi_spe_get();                          //already constructed
00311         
00312         ptr< pi_sp > empty = NULL;
00313         
00314         ptr<pi_sp> tmp = pi_sp::create (NULL,NULL,sp->level_get());     //Dont mix ordering of commands below !
00315         
00316         sp->pi_spe_set(tmp);
00317         
00318         if (sp->psp_get()) tmp->psp_set(ss_sp2pi_sp(sp->psp_get()));            //recursion
00319         if (sp->nsp_get()) tmp->nsp_set(ss_sp2pi_sp(sp->nsp_get()));
00320         
00321         plog(spl) << "  SP: ss " <<sp->uid_get() <<" -> pi " << tmp->uid_get() << "\n" << eolog;
00322         
00323         ptr<backend_data_builder> initial_structure_builder = backend_data_builder::instance();
00324         initial_structure_builder->add_sp(tmp);         //backend shall know about constructed sequnce point
00325 
00326         return tmp;
00327 }
00328 
00329 /////////////////////////               Expression visitors             /////////////////////////////////
00330 
00331 
00332 /*!
00333    Check whether given expression was already transformed.
00334    In such a case result is set to according result of evaluated subexpression
00335    and returned TRUE.
00336 */
00337 bool ss_expr2pi::evaluated(ptr< ss_expression > x){
00338         
00339         if ( expr2operand_map->find(x)!=expr2operand_map->end() ) {
00340                 result = (*expr2operand_map)[x]; 
00341                 outry("out - already evaluated");
00342                 return true;
00343          }
00344         return false;
00345 }
00346 
00347 /*!
00348   Assignment transformation.
00349   It distinguishes between store and store via pointer dependently on returned result from subexpression.
00350 */
00351 void ss_expr2pi::visit_ss_assign(ptr< ::lestes::lang::cplus::sem::ss_assign > x ) {entry("=");
00352         
00353                 
00354         if (evaluated(x)) { returned_pointer = (*expr2operand_map)[x]->kind_get()==pi_operand::MEM_PTR_DEREF; return; }
00355         
00356         ptr< pi_pi > res;       
00357         ptr< pi_preg > rt = this->returns_preg(x->right_get()); //rvalue which to store
00358 
00359         if (is_returned_pointer(x->left_get())){        //real evaluation of left operand
00360                                                         //store via pointer
00361                 ptr< pi_mem_ptr_deref > lft = this->returns_mem_pointer(x->left_get());         //pointer to be dereferenced
00362                 ptr< pi_mem_ptr_deref > new_lft = lft->factory_get()->get_mem(NULL).dncast<pi_mem_ptr_deref>();//pozn tohle ma byt v tmp.dest
00363                 
00364                 if (!lft || !rt) lassert2(false,"ss_assign operands incorrect.");
00365                 
00366                 lint level = max (                                              //get level for current pseudoinstruction
00367                                 max( x->psp_get()->level_get(), x->nsp_get()->level_get() ),
00368                                 rt->origin_get()->level_get() 
00369 //                              max( lft->origin_get()->level_get(), rt->origin_get()->level_get() )
00370                         );
00371         
00372                 //JAZ
00373                 level = 1 + max(level,(lint)new_lft->factory_get().dncast<pi_mf_ptr_deref>()->addr_get()->origin_get()->level_get());
00374                 
00375                 ptr< pi_stp > tmp = pi_stp::create(                                     //store equivalent to assignemnt
00376                                 ss_sp2pi_sp(x->psp_get()),
00377                                 ss_sp2pi_sp(x->nsp_get()),
00378                                 level,
00379                                 new_lft,
00380                                 //((lft->factory_get()).dncast<pi_mf_ptr_deref>())->addr_get(),
00381                                 rt,
00382                                 ss_type2tm_type_convertor::instance()->convert(         ///pointer on destination type
00383                                                                 ss_pointer::instance(x->type_get().dncast<ss_pseudoreference>()->what_get())
00384                                                                 ),
00385                                 rt->type_get()
00386                                 
00387                         ); 
00388                 
00389                 new_lft->origin_set(tmp);
00390                 res=tmp;
00391                 (*expr2operand_map)[x]=result=new_lft;//pozn1
00392                 returned_pointer = true; //jaz
00393          }
00394            else                 //store to usual lvalue
00395          {
00396                 ptr< pi_mem > lft = this->returns_mem(x->left_get());           //lvalue where to store
00397         
00398                 if (!lft || !rt) lassert2(false,"ss_assign operands incorrect.");
00399                 
00400                 lint level = 1+max (                                            //get level for current pseudoinstruction
00401                                 max( x->psp_get()->level_get(), x->nsp_get()->level_get() ),
00402                                 rt->origin_get()->level_get() 
00403                         );
00404         
00405                 ptr< pi_st > tmp = pi_st::create(                                       //store equivalent to assignemnt
00406                                 ss_sp2pi_sp(x->psp_get()),
00407                                 ss_sp2pi_sp(x->nsp_get()),
00408                                 level,
00409                                 lft,                    //this is only fake, new pi_mem for lft will be here
00410                                 rt,
00411                                 ss_type2tm_type_convertor::instance()->convert(x->type_get())
00412                         );
00413                 ptr< pi_mem > new_lft = lft->factory_get()->get_mem(tmp);
00414                 tmp->destination_set(new_lft);
00415                 
00416                 res=tmp;
00417                 (*expr2operand_map)[x]=result=new_lft;
00418          }//else
00419          
00420         backend_data_builder::instance()->add_pi(res);
00421         backend_data_builder::instance()->add_rail();
00422         
00423 
00424 outry("=");
00425 }
00426 
00427 /*!
00428   Load proper pi_mem_factory for a given declaration.
00429   In case of & references, which are treated as pointers, 
00430   pointer is read and flag for dereference is set.
00431   For referenced variables origin has to be computed, to determine
00432   correct data flow (e.g. in  a=1+a, where a is used as 
00433   both a load's source and a store's target).
00434 */
00435 void ss_expr2pi::visit_ss_var_ref(ptr< ::lestes::lang::cplus::sem::ss_var_ref > x) {entry("VR");
00436 
00437         bool to_be_dereferenced=ss_type2info::create()->process(x->type_get()) == ss_type2info::SS_REFERENCE;
00438         if  (to_be_dereferenced) { plog(gnl)<<x->uid_get()<<" pointer to be dereferenced\n"; }
00439         
00440         if (evaluated(x)) { returned_pointer=to_be_dereferenced;  return; }
00441         
00442         ptr< pi_mem_factory > var = caller->mem_variable_get(x->var_decl_get());
00443         lassert2(var,"Variable reference not found in variable map.");
00444 
00445         if (to_be_dereferenced) {                               //references shall be treated as pointers
00446 
00447                 ptr< pi_mem > lval  = var->get_mem(compute_origin(var,x->psp_get()));
00448                 lassert(lval->kind_get()!=pi_operand::MEM_PTR_DEREF);
00449                 
00450                 ptr< pi_preg > rval = pi_preg::create(NULL,ss_type2tm_type_convertor::instance()->convert(x->type_get()));
00451         
00452                 ulint level = max(x->psp_get()->level_get(),x->nsp_get()->level_get());
00453         
00454                 ptr< pi_ld > tmp = pi_ld::create (
00455                                 ss_sp2pi_sp(x->psp_get()), ss_sp2pi_sp(x->nsp_get()),
00456                                 1+max(level,lval->origin_get()->level_get()),
00457                                 rval,
00458                                 lval,
00459                                 rval->type_get()
00460                         );
00461                         
00462                 rval->origin_set(tmp);
00463                 
00464                 ptr<backend_data_builder> initial_structure_builder = backend_data_builder::instance();
00465                 initial_structure_builder->add_pi(tmp); 
00466                 initial_structure_builder->add_rail();
00467 
00468 
00469                 ptr< pi_mf_ptr_deref > pointer_factory = pi_mf_ptr_deref::create(               //dereferenced memory placeholder
00470                                         NULL,
00471                                         ss_type2tm_type_convertor::instance()->convert(x->type_get()),
00472                                         rval
00473                                 );
00474 
00475                 returned_pointer=true;          //dereference have to be checked on higher level 
00476                 
00477                 (*expr2operand_map)[x] = result =  pointer_factory->get_mem(rval->origin_get());
00478 
00479          } //ss_reference
00480          
00481                 else    //standard var_ref
00482                  (*expr2operand_map)[x] = result = var->get_mem(compute_origin(var,x->psp_get())); //get pi_mem for variable x
00483         
00484 outry("VR");
00485 }
00486 
00487 /*!
00488   lvalue->rvalue conversion or indirect load via pointer 
00489 */
00490 void ss_expr2pi::visit_ss_get(ptr< ::lestes::lang::cplus::sem::ss_get > x) {entry("get");
00491         
00492         if (evaluated(x)) return;
00493         ptr< pi_pi > res;
00494         
00495         //ptr< pi_operand > tmp_lval  = this->returns(x->expr_get());
00496         bool to_be_dereferenced=ss_type2info::create()->process(x->type_get()) == ss_type2info::SS_REFERENCE;
00497         
00498         if (is_returned_pointer(x->expr_get()) || to_be_dereferenced  /*tmp_lval->kind_get()==pi_operand::MEM_PTR_DEREF */ )            //real evaluation run here
00499          {              //we got pointer for dereference, so load will be via pointer
00500          
00501                 ptr < pi_mem_ptr_deref > lval = this->returns_mem_pointer(x->expr_get());       //pointer to be dereferenced
00502                 //ptr < pi_mem_ptr_deref > lval = tmp_lval.dncast<pi_mem_ptr_deref>();
00503                 
00504                 ptr< pi_preg > rval = pi_preg::create(NULL,ss_type2tm_type_convertor::instance()->convert(x->type_get()));
00505                 
00506                 ulint level = max(x->psp_get()->level_get(),x->nsp_get()->level_get());
00507 
00508                 ptr< pi_ldp > tmp = pi_ldp::create (
00509                                 ss_sp2pi_sp(x->psp_get()), ss_sp2pi_sp(x->nsp_get()),
00510                                 1+max(level,lval->origin_get()->level_get()),
00511                                 rval,
00512                                 //((lval->factory_get()).dncast<pi_mf_ptr_deref>())->addr_get(),
00513                                 lval,
00514                                 rval->type_get(),
00515                                 ss_type2tm_type_convertor::instance()->convert(         ///pointer on source type
00516                                                                 ss_pointer::instance(x->type_get())
00517                                                                 )
00518                         );
00519 
00520                 rval->origin_set(tmp);
00521                 res=tmp;
00522                 (*expr2operand_map)[x] = result = rval;
00523                 
00524          } else
00525          {              //standard rvalue_lvalue conversion
00526                 ptr< pi_operand > lval = this->returns(x->expr_get()); 
00527                 
00528                 lassert(lval->kind_get()!=pi_operand::MEM_PTR_DEREF);
00529                 
00530                 ptr< pi_preg > rval = pi_preg::create(NULL,ss_type2tm_type_convertor::instance()->convert(x->type_get()));
00531         
00532                 ulint level = max(x->psp_get()->level_get(),x->nsp_get()->level_get());
00533         
00534                 ptr< pi_ld > tmp = pi_ld::create (
00535                                 ss_sp2pi_sp(x->psp_get()), ss_sp2pi_sp(x->nsp_get()),
00536                                 1+max(level,lval->origin_get()->level_get()),
00537                                 rval,
00538                                 lval,
00539                                 rval->type_get()
00540                         );
00541                 
00542                 /*
00543                 if ( tmp->uid_get()==1638 ) {
00544                         lassert(false);
00545                 }
00546                 */      
00547 
00548                 rval->origin_set(tmp);
00549                 res=tmp;
00550                 (*expr2operand_map)[x] = result = rval;
00551         }
00552         
00553         ptr<backend_data_builder> initial_structure_builder = backend_data_builder::instance();
00554         initial_structure_builder->add_pi(res); 
00555         initial_structure_builder->add_rail();
00556 
00557 outry("get");
00558 }
00559 
00560 /*!
00561   Transform given expression and check whether pointer for dereference is returned.
00562   Used by (vol)get and assign for identification of dereferenced pointer in operand,which cause load/store via returned pointer.
00563   This can happen via dereferience of ss_pointer or via var_ref of variable with ss_reference type. 
00564   */
00565 bool ss_expr2pi::is_returned_pointer(ptr< ss_expression > x){
00566         returned_pointer=false;
00567         this->returns(x);
00568         if (returned_pointer) {
00569                 returned_pointer=false;
00570                 plog(gnl) << x->uid_get() << " returned pointer\n";
00571                 return true;
00572                 }
00573         return false;
00574 }
00575 
00576 void ss_expr2pi::visit_ss_dereference(ptr< ::lestes::lang::cplus::sem::ss_dereference > x) {entry("deref");
00577 
00578 //      plog(gnl) << x->uid_get() << " returned pointer\n";
00579         
00580         if (evaluated(x)) {returned_pointer=true; return;}
00581                 
00582         ptr< pi_preg > val = this->returns_preg( x->expr_get() );
00583         
00584         ptr< pi_mf_ptr_deref > pointer_factory = pi_mf_ptr_deref::create(               //dereferenced memory placeholder
00585                                         NULL,
00586                                         ss_type2tm_type_convertor::instance()->convert(x->type_get()),
00587                                         val
00588                                 );
00589 
00590         (*expr2operand_map)[x] = result =  pointer_factory->get_mem(val->origin_get());
00591         returned_pointer=true;          //dereference have to be checked on higher level 
00592 
00593 outry("deref");
00594 }
00595 
00596 
00597 void ss_expr2pi::visit_ss_literal(ptr< ::lestes::lang::cplus::sem::ss_literal > x) {entry("lit");
00598         
00599         if (evaluated(x)) return;
00600         ptr < ss_linfo2pi_linfo > cnv = ss_linfo2pi_linfo::create();
00601         ptr< literal_info_base > pinfo = cnv->get_pinfo(x->value_get());
00602         
00603         
00604         ptr < pi_lit > lit = pi_lit::create(NULL,pinfo->type_get(),pinfo);      //origin of literal is always NULL
00605         ptr< pi_preg > dest= pi_preg::create(NULL,pinfo->type_get());
00606         
00607         ptr<backend_data_builder> builder = backend_data_builder::instance();
00608         builder->add_pis( literal_loader::instance()->
00609                                 generate_load(dest, lit, ss_sp2pi_sp(x->psp_get()), ss_sp2pi_sp(x->nsp_get())));
00610         builder->add_rail();    
00611 
00612         (*expr2operand_map)[x]=result=dest;
00613         
00614 outry("lit");   
00615 }
00616 
00617 #define pi_operand_void NULL
00618 
00619 void ss_expr2pi::visit_ss_funcall(ptr< ::lestes::lang::cplus::sem::ss_funcall > x) {entry("funcall");
00620 
00621         if (evaluated(x)) return;
00622         
00623         ptr<mem_alloc_manager> allocator = mem_alloc_manager::instance();
00624         
00625         ptr< ss_destructor_tables > dts = ss_destructor_tables::instance();
00626         ptr<backend_data_builder> builder = backend_data_builder::instance();
00627         
00628         ptr<pi_mem_factory> rv;         //return value
00629         ptr<pi_abstract_function_call> fcall;
00630 
00631         if (x->type_get()->is_void()) {
00632                 
00633                 rv=pi_operand_void;
00634                 fcall = pi_callv::create (
00635                         ss_sp2pi_sp(x->psp_get()), ss_sp2pi_sp(x->nsp_get()),
00636                         0,                              //level - will be filled later
00637                         //jaz list_mem_type::create(),                          //funcall args - will be filled later
00638                         list<srp<pi_operand> >::create(),
00639                         NULL,                           //this; this will be filled only through access operators
00640                         x->function_get()               //declaration
00641                         );                              
00642                 (*expr2operand_map)[x]=result=pi_operand_void;          //checked for return void funcall();
00643                 }
00644                 
00645         else                            //non void return
00646                 {
00647                 
00648                 
00649                 ptr<tm_data_type_base> trvt = ss_type2tm_type_convertor::instance()->convert(x->type_get());
00650                 ptr< pi_call > tmp = pi_call::create (                                  //tmp needed for access to fields
00651                         ss_sp2pi_sp(x->psp_get()), ss_sp2pi_sp(x->nsp_get()),
00652                         0,                              //level - will be filled later
00653                         list<srp<pi_operand> >::create(),
00654                         //list_mem_type::create(),                              //funcall args - will be filled later
00655                         NULL,                           //this; this will be filled only through acces operators
00656                         trvt,           //type  
00657                         NULL,                           //rv
00658                         x->function_get()               //declaration
00659                         );
00660                         
00661                 /* jaz  
00662                 rv = allocator->allocate_fcall_par_ret_val(
00663                                         caller->current_function_get(),         //caller
00664                                         tmp                                     //calee
00665                                 );
00666                 */
00667                 
00668                 if ( trvt->return_reg_get() ) {
00669                         //type is returned in register
00670                         rv = pi_mf_preg::create(NULL,trvt, pi_preg::create(tmp,trvt));  
00671                 } else {
00672                         //type is returned in memory 
00673                         rv = pi_mf_stack::create(NULL,trvt, 0); 
00674                 }
00675                                 
00676                 tmp->rv_set(rv->get_mem(tmp));
00677                 dts->destructor_add_to_destr(temporaries,x->type_get(),rv); 
00678                                 
00679                 fcall=tmp;
00680                 (*expr2operand_map)[x]=result=tmp->rv_get();
00681                 }//else
00682 
00683         //TODO ellipsis
00684         ulint level=max(fcall->psp_get()->level_get(),fcall->nsp_get()->level_get());           // max level from seqeuence points and argumets 
00685         
00686         /*              Parameters              */
00687         //ptr < list_mem_type > fc_args = fcall->args_get();            //args for pi_call
00688         ptr< list<srp<pi_operand> > > fc_args = fcall->args_get();              //args for pi_call
00689         lint i=1;                                               //index of function parameter
00690         ptr < pi_operand > eval_arg;                            //temporary for evaluation of the argument
00691         list < srp<ss_expression> >::iterator iss=x->args_get()->begin();       //argument of funcall in ss
00692 
00693         
00694         for ( ; iss != x->args_get()->end() ;  i++, iss++){             //setting args for pi_call
00695                 
00696                 eval_arg = this->returns(*iss);                         //transform argument expression into pi; evaluates just load of arg
00697                 fc_args->push_back(eval_arg);
00698                 
00699                 if ( eval_arg->origin_get() ) {
00700                         level = max(eval_arg->origin_get()->level_get(),level);
00701                 }
00702                 
00703                 //jaz - convert a pi_operand to pi_mem operand
00704                 /*
00705                 ptr<pi_mem> eval_arg_mem;
00706                 
00707                 switch ( eval_arg->kind_get() ) {
00708                         case pi_operand::PREG: {
00709                                 ptr<pi_mf_preg> mf = pi_mf_preg::create(eval_arg->origin_get(), eval_arg->type_get(), eval_arg.dncast<pi_preg>());
00710                                 eval_arg_mem = mf->get_mem(eval_arg->origin_get()); 
00711                         } break;
00712                         
00713                         case pi_operand::LIT: {
00714                                 ptr<pi_mf_lit> mf = pi_mf_lit::create(NULL, eval_arg->type_get(), eval_arg.dncast<pi_lit>());
00715                                 eval_arg_mem = mf->get_mem(eval_arg->origin_get()); 
00716                         } break;
00717                         
00718                         default:
00719                                 eval_arg_mem = eval_arg.dncast<pi_mem>();
00720                         
00721                 }
00722                 
00723                 fc_args->push_back(eval_arg_mem);
00724                 */
00725                 
00726                 /* jaz
00727                 ptr< pi_mem_factory > arg_alloc = allocator->allocate_fcall_par(caller->current_function_get(),fcall,(*iss)->type_get(), i);
00728                 fc_args->push_back(arg_alloc->get_mem(ss_sp2pi_sp(psp)));
00729                         //temporary for argument on stack; origin on psp of the whole expression
00730         
00731                 ptr < list < srp<pi_pi> > > 
00732                         pis =   copy_constructor_call_generator::instance()->                   //store arg to stack for the function
00733                                         generate(       fc_args->back(),
00734                                                         eval_arg,
00735                                                         ss_sp2pi_sp((*iss)->psp_get()),
00736                                                         ss_sp2pi_sp((*iss)->nsp_get())
00737                                                 );              
00738                 builder->add_pis(pis);
00739                 
00740                 
00741                 list < srp<pi_pi> >::iterator ipi=pis->begin();                 //we have to keep level on maximum of all the instruction levels used
00742                                                                                 //to store argument     
00743                 for ( ; ipi != pis->end() ; ipi++ ) level = max ((*ipi) -> level_get(),level);
00744                 
00745                 dts->destructor_add_to_destr(temporaries,(*iss)->type_get(),fc_args->back()->factory_get());
00746                 */
00747         }
00748 
00749         fcall->args_set(fc_args);
00750         fcall->level_set(level+1);
00751         
00752         builder->add_pi(fcall); 
00753         builder->add_rail();    
00754 
00755 outry("funcall");
00756 }
00757 
00758 /*template<typename Ss, typename Pi>
00759 void binary_op_visit_template(ptr< ss_expr2pi > This, ptr< Ss > x){entry("X");
00760         
00761         if (This->evaluated(x)) return;
00762 
00763         ptr< pi_preg > rt = This->returns_preg(x->right_get()); //evaluate operands
00764         ptr< pi_preg > lft= This->returns_preg(x->left_get());  
00765         ptr< pi_preg > dest= pi_preg::create(NULL,ss_type2tm_type_convertor::instance()->convert(x->type_get()));
00766         
00767         if (!lft || !rt) lassert2(false,"operands incorrect.");
00768 
00769         lint level = 1+max (                                                    //get level for current pseudoinstruction
00770                         max( x->psp_get()->level_get(), x->nsp_get()->level_get() ),
00771                         max( lft->origin_get()->level_get(), rt->origin_get()->level_get() )
00772                 );
00773         
00774         ptr< pi_add > tmp = pi_add::create(                                     //store equivalent to assignemnt
00775                                 ss_sp2pi_sp(x->psp_get()),
00776                                 ss_sp2pi_sp(x->nsp_get()),
00777                                 level,
00778                                 lft,
00779                                 rt,
00780                                 dest,
00781                                 dest->type_get()
00782                                 );
00783 
00784         dest->origin_set(tmp);
00785                 
00786         backend_data_builder::instance()->add_pi(tmp);
00787         backend_data_builder::instance()->add_rail();
00788         
00789         (*This->expr2operand_map)[x]=This->result=lft;
00790 
00791 
00792 outry("X");
00793 }//template
00794 */
00795 
00796 /*!
00797   Generic visitor for ss -> pi transformation of binary operators
00798   Level for pseudoinstructions: maximum(psp,nsp,lft,rt) + 1
00799 */
00800 
00801 #define BIND_EQUAL_SS_PI(OP,second_type...) \
00802 void ss_expr2pi::visit_ss_##OP(ptr<ss_##OP> x){entry(#OP);\
00803 \
00804         if (evaluated(x)) return;\
00805 \
00806         ptr< pi_preg > rt = returns_preg(x->right_get());       \
00807         ptr< pi_preg > lft= returns_preg(x->left_get());        \
00808         ptr< pi_preg > dest= pi_preg::create(NULL,ss_type2tm_type_convertor::instance()->convert(x->type_get()));\
00809 \
00810         if (!lft || !rt) lassert2(false,"operands incorrect.");\
00811 \
00812         lint level = 1+max (                                                            \
00813                         max( x->psp_get()->level_get(), x->nsp_get()->level_get() ),    \
00814                         max( lft->origin_get()->level_get(), rt->origin_get()->level_get() )\
00815                 );\
00816 \
00817         ptr< pi_##OP > tmp = pi_##OP::create(                   \
00818                                 ss_sp2pi_sp(x->psp_get()),      \
00819                                 ss_sp2pi_sp(x->nsp_get()),      \
00820                                 level,                          \
00821                                 lft,                            \
00822                                 rt,                             \
00823                                 dest,                           \
00824                                 dest->type_get(),               \
00825                                 ## second_type                  \
00826                                 );                              \
00827 \
00828         dest->origin_set(tmp);\
00829 \
00830         backend_data_builder::instance()->add_pi(tmp);\
00831         backend_data_builder::instance()->add_rail();\
00832 \
00833         (*expr2operand_map)[x]=result=dest;\
00834 \
00835 outry(#OP);\
00836 }
00837 
00838 
00839 #define second_type_arg (rt->type_get())
00840 
00841 BIND_EQUAL_SS_PI(add);
00842 BIND_EQUAL_SS_PI(sub);
00843 BIND_EQUAL_SS_PI(mul);
00844 BIND_EQUAL_SS_PI(div);  //TODO there are more possibilities
00845 BIND_EQUAL_SS_PI(mod);
00846 BIND_EQUAL_SS_PI(shr);
00847 BIND_EQUAL_SS_PI(shl);
00848 //TODO shr -> sar for signed
00849 //TODO shl -> sal for signed
00850 
00851 
00852 BIND_EQUAL_SS_PI(band);
00853 BIND_EQUAL_SS_PI(bor);
00854 BIND_EQUAL_SS_PI(bxor);
00855 
00856 //TODO arr_acc
00857 
00858 BIND_EQUAL_SS_PI(sbg,second_type_arg);
00859 BIND_EQUAL_SS_PI(sbl,second_type_arg);
00860 BIND_EQUAL_SS_PI(sbe,second_type_arg);
00861 BIND_EQUAL_SS_PI(sbng,second_type_arg);
00862 BIND_EQUAL_SS_PI(sbnl,second_type_arg);
00863 BIND_EQUAL_SS_PI(sbne,second_type_arg);
00864 
00865 
00866 /*!
00867   Generic visitor for ss -> pi transformation of unary operators
00868   Level for pseudoinstructions: maximum(psp,nsp,lft,rt) + 1
00869 */
00870 #define BIND_UNARY_EQUAL_SS_PI(OP) \
00871 void ss_expr2pi::visit_ss_##OP(ptr<ss_##OP> x){entry(#OP);\
00872 \
00873         if (evaluated(x)) return;\
00874 \
00875         ptr< pi_preg > src = returns_preg(x->expr_get());       \
00876         ptr< pi_preg > dest= pi_preg::create(NULL,ss_type2tm_type_convertor::instance()->convert(x->type_get()));\
00877 \
00878         lassert2(src,"operands incorrect.");\
00879 \
00880         lint level = 1+max (                                                            \
00881                         max( x->psp_get()->level_get(), x->nsp_get()->level_get() ),    \
00882                         src->origin_get()->level_get()\
00883                 );\
00884 \
00885         ptr< pi_##OP > tmp = pi_##OP::create(                   \
00886                                 ss_sp2pi_sp(x->psp_get()),      \
00887                                 ss_sp2pi_sp(x->nsp_get()),      \
00888                                 level,                          \
00889                                 src,                            \
00890                                 dest,                           \
00891                                 dest->type_get()                \
00892                                 );                              \
00893 \
00894         dest->origin_set(tmp);\
00895 \
00896         backend_data_builder::instance()->add_pi(tmp);\
00897         backend_data_builder::instance()->add_rail();\
00898 \
00899         (*expr2operand_map)[x]=result=dest;\
00900 \
00901 outry(#OP);\
00902 }
00903 
00904 BIND_UNARY_EQUAL_SS_PI(gat);
00905 BIND_UNARY_EQUAL_SS_PI(neg);
00906 BIND_UNARY_EQUAL_SS_PI(lnot);
00907 BIND_UNARY_EQUAL_SS_PI(bnot);
00908 
00909 
00910 /*!
00911   lvalue->rvalue conversion or indirect load via pointer on volatile variable 
00912 */
00913 void ss_expr2pi::visit_ss_vol_get(ptr< ::lestes::lang::cplus::sem::ss_vol_get > x) {entry("vol_get");
00914         
00915         if (evaluated(x)) return;
00916         ptr< pi_pi > res;
00917         
00918         if (is_returned_pointer(x->expr_get()))         //real evaluation run here
00919          {              //we got pointer for dereference, so load will be via pointer
00920          
00921                 ptr< pi_mem_ptr_deref > mem = this->returns_mem_pointer(x->expr_get());
00922                 
00923                 //ptr < pi_preg > lval = this->returns_preg(x->expr_get());     //pointer to be dereferenced
00924                 ptr< pi_preg > rval = pi_preg::create(NULL,ss_type2tm_type_convertor::instance()->convert(x->type_get()));
00925                 
00926                 //JAZ
00927                 ptr<pi_sp> psp = ss_sp2pi_sp(x->psp_get());
00928                 ptr<pi_sp> nsp = ss_sp2pi_sp(x->nsp_get());
00929                 
00930                 //ptr<pi_mf_ptr_deref> mf = pi_mf_ptr_deref::create(NULL, rval->type_get(),lval);
00931                 //ptr<pi_mem_ptr_deref> mem = mf->get_mem(compute_origin(mf,x->psp_get())).dncast<pi_mem_ptr_deref>();
00932                 
00933                 //ulint level = max(x->psp_get()->level_get(),x->nsp_get()->level_get());
00934                 ulint level = max(psp->level_get(),nsp->level_get());
00935 
00936                 ptr< pi_ldpv > tmp = pi_ldpv::create (
00937                                 psp, nsp,
00938                                 1+max(level,mem->origin_get()->level_get()),
00939                                 rval,
00940                                 mem,
00941                                 rval->type_get(),
00942                                 ss_type2tm_type_convertor::instance()->convert(         ///pointer on source type
00943                                                                 ss_pointer::instance(x->type_get().dncast<ss_pseudoreference>()->what_get())
00944                                                                 )
00945                         );
00946                 
00947                 rval->origin_set(tmp);
00948                 res=tmp;
00949                 (*expr2operand_map)[x] = result = rval;
00950                 
00951          } else
00952          {              //standard rvalue_lvalue conversion
00953          
00954                 ptr< pi_mem > lval  = this->returns_mem(x->expr_get());
00955                 lassert(lval->kind_get()!=pi_operand::MEM_PTR_DEREF);
00956                 
00957                 ptr< pi_preg > rval = pi_preg::create(NULL,ss_type2tm_type_convertor::instance()->convert(x->type_get()));
00958         
00959                 ulint level = max(x->psp_get()->level_get(),x->nsp_get()->level_get());
00960         
00961                 ptr< pi_ldv > tmp = pi_ldv::create (
00962                                 ss_sp2pi_sp(x->psp_get()), ss_sp2pi_sp(x->nsp_get()),
00963                                 1+max(level,lval->origin_get()->level_get()),
00964                                 rval,
00965                                 lval,
00966                                 rval->type_get()
00967                         );
00968                 
00969                 rval->origin_set(tmp);
00970                 res=tmp;
00971                 (*expr2operand_map)[x] = result = rval;
00972         }
00973         
00974         ptr<backend_data_builder> initial_structure_builder = backend_data_builder::instance();
00975         initial_structure_builder->add_pi(res); 
00976         initial_structure_builder->add_rail();
00977 
00978 outry("vol_get");
00979 }
00980 
00981 /*!
00982   This time, templates should be instantiated.
00983 */
00984 void ss_expr2pi::visit_ss_var_ref_by_qname(ptr< ::lestes::lang::cplus::sem::ss_var_ref_by_qname > ) {
00985         lassert2(false,"Reference to unistantiated template.");
00986 }
00987 
00988 /*!
00989   Up to now, there is nothing to be done for array->pointer conversion.
00990 */
00991 void ss_expr2pi::visit_ss_array_to_pointer(ptr< ::lestes::lang::cplus::sem::ss_array_to_pointer > x){entry("array->pointer");
00992 
00993         if (evaluated(x)) return;
00994         
00995         (*expr2operand_map)[x] = result = this->returns(x->expr_get()) ;
00996         
00997 outry("array->pointer");        
00998 }
00999 
01000 /*!
01001   Conversion between types.
01002   Note, that frontend products conversions, where source type is equal destination
01003   type. These cases must be properly treated.
01004 */
01005 void ss_expr2pi::visit_ss_conversion(ptr< ::lestes::lang::cplus::sem::ss_conversion > x) {entry("convert");
01006         if (evaluated(x)) return;
01007         
01008         if (x->type_get()==x->src_type_get()) {         //conversion is meaningful only on different types
01009                 ptr< pi_operand > src = this->returns(x->expr_get());
01010                 (*expr2operand_map)[x]=result=src; 
01011                 outry("convert(identity)");
01012                 return; 
01013          } 
01014         
01015         ptr < pi_preg > src = this->returns_preg(x->expr_get());        //pointer to be dereferenced
01016         ptr< pi_preg > dest = pi_preg::create(NULL,ss_type2tm_type_convertor::instance()->convert(x->type_get()));
01017 
01018         lint level = 1+max ( src->origin_get()->level_get(),
01019                         max( x->psp_get()->level_get(), x->nsp_get()->level_get() ));
01020                         
01021         ptr< pi_cvt > tmp = pi_cvt::create(
01022                                 ss_sp2pi_sp(x->psp_get()),
01023                                 ss_sp2pi_sp(x->nsp_get()),
01024                                 level,
01025                                 src,
01026                                 dest,
01027                                 ss_type2tm_type_convertor::instance()->convert(x->type_get()),
01028                                 ss_type2tm_type_convertor::instance()->convert(x->src_type_get())
01029                 );
01030         
01031         dest->origin_set(tmp);
01032 
01033         backend_data_builder::instance()->add_pi(tmp);
01034         backend_data_builder::instance()->add_rail();
01035 
01036         (*expr2operand_map)[x]=result=dest;
01037 
01038 outry("convert");
01039 }
01040 
01041 /*!
01042   Load address of a given object (&x).
01043   Only lvalue can be the argument of this operator.
01044 */
01045 void ss_expr2pi::visit_ss_address_of(ptr< ::lestes::lang::cplus::sem::ss_address_of > x) {entry("reference");
01046 
01047         if (evaluated(x)) return;
01048         
01049         ptr < pi_mem > src = this->returns_mem(x->expr_get());          //address to be loaded
01050         ptr< pi_preg > dest = pi_preg::create(NULL,ss_type2tm_type_convertor::instance()->convert(x->type_get()));
01051 
01052         lint level = 1+max ( src->origin_get()->level_get(),
01053                         max( x->psp_get()->level_get(), x->nsp_get()->level_get() ));
01054         
01055         ptr< pi_lda > tmp = pi_lda::create(
01056                                 ss_sp2pi_sp(x->psp_get()),
01057                                 ss_sp2pi_sp(x->nsp_get()),
01058                                 level,
01059                                 dest,
01060                                 src,
01061                                 dest->type_get(),
01062                                 src->type_get()
01063                 );
01064         
01065         dest->origin_set(tmp);
01066 
01067         backend_data_builder::instance()->add_pi(tmp);
01068         backend_data_builder::instance()->add_rail();
01069 
01070         (*expr2operand_map)[x]=result=dest;
01071 
01072 
01073 outry("reference");
01074 }
01075 
01076 /*!
01077   Bind reference. It can occurs in initialization, function parameter passing and return value store.
01078   Its input value shall be lvalue - in case of dereference on pointer, only pointer shall be returned,
01079   in case of variable reference, its address shall be loaded.
01080 */
01081 void ss_expr2pi::visit_ss_bind_reference(ptr< ::lestes::lang::cplus::sem::ss_bind_reference > x) {entry("bind_ref");
01082         
01083         if (evaluated(x)) return;
01084         
01085         if (is_returned_pointer(x->expr_get()))         //real evaluation run here
01086          {              //we got pointer dereference, so we simply return it
01087          
01088                 ptr < pi_preg > lval = this->returns_preg(x->expr_get());       //pointer
01089                 (*expr2operand_map)[x] = result = lval;
01090                 
01091          } else
01092          {              //var_ref address to load
01093          
01094                 ptr< pi_mem > var  = this->returns_mem(x->expr_get());
01095                 ptr< pi_preg > addr = pi_preg::create(NULL,ss_type2tm_type_convertor::instance()->convert(x->type_get()));
01096         
01097                 ulint level = max(x->psp_get()->level_get(),x->nsp_get()->level_get());
01098 
01099                 ptr< pi_lda > tmp = pi_lda::create (
01100                                 ss_sp2pi_sp(x->psp_get()), ss_sp2pi_sp(x->nsp_get()),
01101                                 1+max(level,var->origin_get()->level_get()),
01102                                 addr,
01103                                 var,
01104                                 addr->type_get(),
01105                                 var->type_get()
01106                         );
01107 
01108                 addr->origin_set(tmp);
01109                 (*expr2operand_map)[x] = result = addr;
01110                 
01111                 ptr<backend_data_builder> initial_structure_builder = backend_data_builder::instance();
01112                 initial_structure_builder->add_pi(tmp); 
01113                 initial_structure_builder->add_rail();
01114 
01115         } //else
01116         
01117 outry("bind_ref");
01118 }
01119 
01120 
01121 //These visitors shall be implemented in the future
01122 
01123 void ss_expr2pi::visit_ss_land(ptr< ::lestes::lang::cplus::sem::ss_land > ) {
01124 lassert2(false,"Visitor of && expression not implemented in ss2pi\n");
01125 //TODO
01126 }
01127 
01128 void ss_expr2pi::visit_ss_lor(ptr< ::lestes::lang::cplus::sem::ss_lor > ) {
01129 lassert2(false,"Visitor of || expression not implemented in ss2pi\n");
01130 //TODO
01131 }
01132 
01133 void ss_expr2pi::visit_ss_arr_acc(ptr< ::lestes::lang::cplus::sem::ss_arr_acc > ) {
01134 lassert2(false,"Visitor of array access expression not implemented in ss2pi\n");
01135 //TODO
01136 }
01137 
01138 void ss_expr2pi::visit_ss_pfuncall(ptr< ::lestes::lang::cplus::sem::ss_pfuncall > ) {
01139 lassert2(false,"Visitor of pfuncall expression not implemented in ss2pi\n");
01140 //TODO
01141 }
01142 
01143 void ss_expr2pi::visit_ss_ifuncall(ptr< ::lestes::lang::cplus::sem::ss_ifuncall > ) {
01144 lassert2(false,"Visitor of ifuncall expression not implemented in ss2pi\n");
01145 //TODO
01146 }
01147 
01148 void ss_expr2pi::visit_ss_mfuncall(ptr< ::lestes::lang::cplus::sem::ss_mfuncall > ) {
01149 lassert2(false,"Visitor of mfuncall expression not implemented in ss2pi\n");
01150 //TODO
01151 }
01152 
01153 void ss_expr2pi::visit_ss_vfuncall(ptr< ::lestes::lang::cplus::sem::ss_vfuncall > ) {
01154 lassert2(false,"Visitor of vfuncall expression not implemented in ss2pi\n");
01155 //TODO
01156 }
01157 
01158 void ss_expr2pi::visit_ss_bind_to_temporary(ptr< ::lestes::lang::cplus::sem::ss_bind_to_temporary > ) {
01159 lassert2(false,"Visitor of bind-to-temporary expression not implemented in ss2pi\n");
01160 //TODO
01161 }
01162 
01163 void ss_expr2pi::visit_ss_this_expr(ptr< ::lestes::lang::cplus::sem::ss_this_expr > ) {
01164 lassert2(false,"Visitor of 'this' expression not implemented in ss2pi\n");
01165 //TODO
01166 }
01167 
01168 void ss_expr2pi::visit_ss_ternary(ptr< ::lestes::lang::cplus::sem::ss_ternary > ) {
01169 lassert2(false,"Visitor of ternary expression not implemented in ss2pi\n");
01170 //TODO
01171 }
01172 
01173 void ss_expr2pi::visit_ss_throw(ptr< ::lestes::lang::cplus::sem::ss_throw > ) {
01174 lassert2(false,"Visitor of throe expression not implemented in ss2pi\n");
01175 //TODO
01176 }
01177 
01178 void ss_expr2pi::visit_ss_member_ptr(ptr< ::lestes::lang::cplus::sem::ss_member_ptr > ) {
01179 lassert2(false,"Visitor of member pointer expression not implemented in ss2pi\n");
01180 //TODO
01181 }
01182 
01183 void ss_expr2pi::visit_ss_ptr_member_ptr(ptr< ::lestes::lang::cplus::sem::ss_ptr_member_ptr > ) {
01184 lassert2(false,"Visitor of current expression not implemented in ss2pi\n");
01185 //TODO
01186 }
01187 
01188 void ss_expr2pi::visit_ss_access(ptr< ::lestes::lang::cplus::sem::ss_access > ) {
01189 lassert2(false,"Visitor of accessing operator not implemented in ss2pi\n");
01190 //TODO
01191 }
01192 
01193 void ss_expr2pi::visit_ss_ptr_access(ptr< ::lestes::lang::cplus::sem::ss_ptr_access > ) {
01194 lassert2(false,"Visitor of pointer accessing operator expression not implemented in ss2pi\n");
01195 //TODO
01196 }
01197 
01198 
01199 /////////////////////           Destination visitors            ///////////////////////////
01200 
01201 /*!
01202   We should not ask for another expressions.
01203 */
01204 void ss_expr2destination::default_destination(ptr< ::lestes::lang::cplus::sem::ss_expression > ){
01205         lassert2(false,"Trying to get destination from non-side-effect expression.");
01206 }
01207 
01208 /*!
01209   There is no destination for funcall.
01210 */
01211 void ss_expr2destination::visit_ss_funcall(ptr< ::lestes::lang::cplus::sem::ss_funcall > ){
01212         destination=NULL;       
01213 }
01214 
01215 /*!
01216   Destination for assignment is left operand.
01217 */
01218 void ss_expr2destination::visit_ss_assign(ptr< ::lestes::lang::cplus::sem::ss_assign > x){
01219         destination=x->left_get();
01220 }
01221 
01222 /*!
01223   Destination for volatile access is accessed variable itself.
01224 */
01225 void ss_expr2destination::visit_ss_vol_get(ptr< ::lestes::lang::cplus::sem::ss_vol_get > x){
01226         destination=x->expr_get();
01227 }
01228 
01229 
01230 
01231 /////////////////////////               Statement Visitors              /////////////////////////////////
01232 
01233 /*!
01234   Entering new compound statement
01235 */
01236 void ss_stmt2pi::visit_ss_compound_stmt(ptr< ss_compound_stmt > x){entry("compound");
01237 
01238         ptr< ss_stmt2pi > stmt_visitor =                        //new visitor
01239                 ss_stmt2pi::create( this->current_function_get(), local_variable_map, namespace_variable_map );
01240         
01241         ptr< ss_destructor_tables > dts = ss_destructor_tables::instance();     //new destructor table for variables on compound
01242         dts->open_compound_stmt(x);
01243         
01244         list < srp<ss_statement> >::iterator is=x->statements_get()->begin();
01245         
01246         for ( ; is != x->statements_get()->end() ; is++ ){
01247                 (*is) -> accept_ss_statement_visitor(stmt_visitor);
01248         }
01249         
01250         if (current_function)                   //TODO global destruction folows ABI
01251         dts->back_roll_from_current_compound_stmt();
01252         dts->close_compound_stmt();
01253 
01254 outry("compound");      
01255 }
01256 
01257 void ss_stmt2pi::visit_ss_decl_stmt(ptr< ss_decl_stmt > x){ 
01258 
01259         ptr< ss_decl2pi > decl_visitor = ss_decl2pi::create(this,x);
01260         x->decl_get()->accept_ss_declaration_visitor(decl_visitor);
01261         
01262         //initializations are done inside declaration
01263 }
01264 
01265 
01266 /*!
01267   Common entry point for expression to pi tranformation, since there are more ways
01268   how to get into ss_expression - through expression statement initializer or conditions in other statements.
01269   
01270   Parameters:           
01271                         stmt- decl/expr statement from wherewe are calling start_ss_expr2pi     
01272                         stmt_caller - statement visitor, which is calling this routine
01273   Used variables:
01274                                 psp - previous sequence point for the whole expression needed for
01275                                         for origin lookup.
01276                                 nsp - needed for building of temporaries destruction
01277 
01278 */
01279 #define start_ss_expr2pi(stmt,stmt_caller) \
01280         ptr< expression_results_map_type > expr2operand = expression_results_map_type::create();\
01281         ptr< ss_destructor_table > temporaries = ss_destructor_table::create(NULL);\
01282         plog(dtl) << "New temporaries table " << temporaries->uid_get()<<"\n" << eolog;\
01283         ptr< ss_expr2pi > expr_visitor = ss_expr2pi::create(stmt_caller,stmt->psp_get(),temporaries,expr2operand);\
01284 \
01285         list < srp<ss_sp> > ::iterator i = stmt->sequence_points_get()->begin();\
01286         for ( ; i != stmt->sequence_points_get()->end(); i++) { \
01287 \
01288                 list < srp<ss_se> >::iterator ii = (*i)->nse_get()->begin();    \
01289                 for ( ; ii != (*i)->nse_get()->end(); ii++){                    \
01290                         expr_visitor->returns((*ii)->from_get());               \
01291                 }       \
01292         }       \
01293         
01294                                                                                 
01295 
01296 void ss_stmt2pi::visit_ss_return(ptr< ss_return > x){entry("return");
01297         
01298         start_ss_expr2pi(x,this);
01299         
01300         ptr< pi_operand > res ;
01301         if (x->result_get()) res = expr_visitor->returns(x->result_get());      //sideeffect evaluation is not enough, we need to know result of the whole expression
01302                 else 
01303                         res=NULL;       //no return expression
01304                         
01305         ptr< backend_data_builder > builder = backend_data_builder::instance();
01306         
01307         ptr< pi_sp > first = ss_sp2pi_sp(x->nsp_get());                         //psp<->first :expresion
01308         ptr< pi_sp > last  = ss_sp2pi_sp(x->nsp_get()->nsp_get());      
01309         ptr< pi_sp > temp   = pi_sp::create(first,last,first->level_get());//first(med)<->destr_compound :temporaries deletion
01310         first->nsp_set(temp);last->psp_set(temp);                               //destr_compound<->temp :compound destructors
01311         builder->add_sp(temp);                                                  //temp<->last :pi_leave
01312         plog(spl) << "  SP: pi_sp for temp deletion : " <<temp->uid_get() <<
01313                         " inserted between " <<first->uid_get()<<" "<<last->uid_get()<<"\n" <<eolog;            
01314         
01315         ptr< pi_sp > med   = first;                                     //first<->med :retval store
01316         if (res) {                      //non_void result has to be stored into ret_value
01317                 med   = pi_sp::create(first,temp,first->level_get());
01318                 builder->add_sp(med);
01319                 
01320                 first->nsp_set(med); temp->psp_set(med);
01321                 
01322                 plog(spl) << "  SP: pi_sp for retval : " <<med->uid_get() << 
01323                                 " inserted between " <<first->uid_get()<<" "<<temp->uid_get()<<"\n" <<eolog;            
01324                 builder->add_pis(
01325                         copy_constructor_call_generator::instance()->           //copy ret value between first and med
01326                           generate(
01327                                 (function_parameter_accessor::instance(current_function)->get_ret_val())->
01328                                                 get_mem(ss_sp2pi_sp(x->psp_get())),
01329                                 res,
01330                                 first,
01331                                 med)
01332                         );
01333         }       
01334         
01335         ptr< pi_sp > destr_compound = temporaries->back_roll_table(med,temp);   //Temporaries destructors will be made between statement sequence points
01336         ss_destructor_tables::instance()->back_roll_from_function(destr_compound,temp); //destructors for local variables in the function
01337 
01338         ptr< pi_leave > tmp = pi_leave::create( temp,last,last->level_get()+1,current_function );
01339         builder->add_pi(tmp);
01340         builder->add_rail();
01341         
01342 outry("return");
01343 }
01344 
01345 /*!
01346   Expression statement. Most expressions are reached through this statement.
01347 */
01348 void ss_stmt2pi::visit_ss_expr_stmt(ptr< ss_expr_stmt > x){     // start of expression tranformation
01349 
01350         start_ss_expr2pi(x,this);               //common starting sequence for expressioon transformation
01351         
01352         temporaries->back_roll_table(ss_sp2pi_sp(x->nsp_get()),ss_sp2pi_sp(x->nsp_get()->nsp_get()));   //Temporaries destructors will be made between statement sequence points
01353 
01354 }
01355 
01356 /*!
01357   If statement. Optimalizations could be done through pi_bX pseudoinstructions.
01358 */
01359 void ss_stmt2pi::visit_ss_if_stmt(ptr< ss_if_stmt > x){entry("if"); 
01360                 
01361         start_ss_expr2pi(x,this);
01362         ptr< pi_preg > res = expr_visitor->returns_preg(x->condition_get());    
01363                 //sideeffect evaluation is not enough, we need to know result of the whole expression
01364                 //for optimalization on branch type, here should be the special expression visitor
01365         
01366         lint level = 1+max ( res->origin_get()->level_get(),
01367                         max( x->psp_get()->level_get(), x->nsp_get()->level_get() ));
01368         
01369         ptr< pi_bf > tmp = pi_bf::create(                       //if false jump to else branch
01370                                 ss_sp2pi_sp(x->psp_get()),
01371                                 ss_sp2pi_sp(x->nsp_get()),
01372                                 level,
01373                                 res,
01374                                 ss_sp2pi_sp(x->celse_get()->psp_get())  //there is always else compound statement
01375         );
01376         
01377         ptr< pi_ba > tmp2 = pi_ba::create(                      //skip else branch
01378                                 ss_sp2pi_sp(x->cthen_get()->nsp_get()),
01379                                 ss_sp2pi_sp(x->celse_get()->psp_get()),
01380                                 1+max(  x->cthen_get()->nsp_get()->level_get(), 
01381                                         x->celse_get()->psp_get()->level_get() 
01382                                      ),
01383                                 ss_sp2pi_sp(x->parent_get()->destructor_sp_get())
01384         );
01385         
01386         
01387         backend_data_builder::instance()->add_pi(tmp);
01388         backend_data_builder::instance()->add_pi(tmp2);
01389         backend_data_builder::instance()->add_rail();
01390         
01391         temporaries->back_roll_table(ss_sp2pi_sp(x->nsp_get()),ss_sp2pi_sp(x->nsp_get()->nsp_get()));   //Temporaries destructors will be made between statement sequence points
01392 
01393 outry("if");
01394 }
01395 
01396 /*!
01397   While statement. 
01398   break and continue jumps are not implemented yet.
01399 */
01400 void ss_stmt2pi::visit_ss_while(ptr< ss_while > x){entry("while");
01401                 
01402         start_ss_expr2pi(x,this);
01403         ptr< pi_preg > res = expr_visitor->returns_preg(x->condition_get());    
01404                 //sideeffect evaluation is not enough, we need to know result of the whole expression
01405                 //for optimalization on branch type, here should be the special expression visitor
01406         
01407         lint level = 1+max ( res->origin_get()->level_get(),
01408                         max( x->psp_get()->level_get(), x->nsp_get()->level_get() ));
01409         
01410         ptr< pi_bf > tmp = pi_bf::create(                       //jump is always to else branch
01411                                 ss_sp2pi_sp(x->psp_get()),
01412                                 ss_sp2pi_sp(x->nsp_get()),
01413                                 level,
01414                                 res,
01415                                 ss_sp2pi_sp(x->parent_get()->destructor_sp_get())       //there is always else compound statement
01416         );
01417         
01418         ptr< pi_ba > tmp2 = pi_ba::create(                      //continue new loop
01419                                 ss_sp2pi_sp(x->body_get()->nsp_get()),
01420                                 ss_sp2pi_sp(x->parent_get()->destructor_sp_get()),
01421                                 1+max(  x->body_get()->nsp_get()->level_get(), 
01422                                         x->parent_get()->destructor_sp_get()->level_get() 
01423                                      ),
01424                                 ss_sp2pi_sp(x->psp_get())
01425         );
01426         
01427         
01428         backend_data_builder::instance()->add_pi(tmp);
01429         backend_data_builder::instance()->add_pi(tmp2);
01430         backend_data_builder::instance()->add_rail();
01431         
01432         temporaries->back_roll_table(ss_sp2pi_sp(x->nsp_get()),ss_sp2pi_sp(x->nsp_get()->nsp_get()));   //Temporaries destructors will be made between statement sequence points
01433 
01434 outry("while");
01435 }
01436 
01437 
01438 //following visitors should be implemented later
01439 
01440 void ss_stmt2pi::visit_ss_try(ptr< ss_try > ){ 
01441 lassert2(false,"Visitor of try statement is not implemented now in ss2pi.\n");
01442 //TODO
01443 }
01444 
01445 void ss_stmt2pi::visit_ss_break(ptr< ss_break > ){ 
01446 lassert2(false,"Visitor of break statement is not implemented now in ss2pi.\n");
01447 //TODO
01448 }
01449 
01450 void ss_stmt2pi::visit_ss_goto(ptr< ss_goto > ){ 
01451 lassert2(false,"Visitor of goto statement is not implemented now in ss2pi.\n");
01452 //TODO
01453 }
01454 
01455 void ss_stmt2pi::visit_ss_continue(ptr< ss_continue > ){ 
01456 lassert2(false,"Visitor of continue statement is not implemented now in ss2pi.\n");
01457 //TODO
01458 }
01459 
01460 void ss_stmt2pi::visit_ss_catch(ptr< ss_catch > ){ 
01461 lassert2(false,"Visitor of catch statement is not implemented now in ss2pi.\n");
01462 //TODO
01463 }
01464 
01465 void ss_stmt2pi::visit_ss_switch_stmt(ptr< ss_switch_stmt > ){ 
01466 lassert2(false,"Visitor of switch statement is not implemented now in ss2pi.\n");
01467 //TODO
01468 }
01469 
01470 void ss_stmt2pi::visit_ss_do(ptr< ss_do > ){ 
01471 lassert2(false,"Visitor of 'do' statement is not implemented now in ss2pi.\n");
01472 //TODO
01473 }
01474 
01475 void ss_stmt2pi::visit_ss_for(ptr< ss_for > ){ 
01476 lassert2(false,"Visitor of for statement is not implemented now in ss2pi.\n");
01477 //TODO
01478 }
01479 
01480 void ss_stmt2pi::mem_variable_set(ptr< ss_declaration > x, ptr< pi_mem_factory > y){
01481         
01482         if(current_function)            //variable on local scope
01483                 (*local_variable_map)[x]=y;
01484          else
01485                 (*namespace_variable_map)[x]=y;
01486 }
01487 
01488 
01489 /*!
01490   This code presumes, there si no ss_fake_declaration on namespace scope.
01491 */
01492 ptr< pi_mem_factory > ss_stmt2pi::mem_variable_get(ptr< ss_declaration > x){
01493 //dumb(x);
01494                 //try to find on namespace scope firstly
01495 
01496         variable_map_type::iterator it = (*namespace_variable_map).find(x);
01497         if ( it != (*namespace_variable_map).end())
01498                 return (*it).second;
01499         
01500                 //try to find on a local scope
01501         
01502         it = (*local_variable_map).find(x);
01503         if ( it != (*local_variable_map).end() )
01504                 return (*it).second;
01505                 
01506          else {         //not yet searched funcall parameter or alias declaration
01507                 ptr< pi_mem_factory > res = ss_decl2mem::create(this)->get_real_decl_mem(x);
01508                 if (res) (*local_variable_map)[x]=res;
01509                 return res;
01510               } //else 
01511                 
01512         return NULL;            //doesnt exists
01513 }
01514 
01515 
01516 
01517 //////////////////////////      DECLARATIONS            /////////////////////////////////
01518 
01519 
01520 void ss_decl2pi::visit_ss_function_declaration(ptr< ss_function_declaration > x){entry("fundecl");      //we will transform current function
01521         
01522         if (!x->body_get()){                            //only function declaration
01523                 outry("fundecl - no body");
01524                 return;
01525         }
01526         
01527         ptr < variable_map_type > vm = variable_map_type::create();     //for each function there is map of variables and their correspond memory placeholders
01528         
01529         ptr< ss_stmt2pi > stmt_visitor = ss_stmt2pi::create(x,vm,caller->namespace_variable_map_get());         //new visitor - new destructor list has to be created
01530         
01531         ptr<backend_data_builder> initial_structure_builder = backend_data_builder::instance();
01532         initial_structure_builder->add_function_start(x);               //backend shall know about processing new function
01533         
01534         x->body_get()->accept_ss_statement_visitor(stmt_visitor);               //no destructors needed 
01535                                                                         //- served by nested compound statement
01536                                                                         // special case of main function is governed by backend itself
01537         initial_structure_builder->add_function_end();
01538 
01539 //      summary_seq_points( x->body_get()->psp_get() );         //debug dump for top level sequence points
01540         
01541 outry("fundecl");       
01542 }
01543 
01544 /*!
01545   In case of object declaration new variable shall be created.
01546   Only basic initializations are implemented here and many TODOs have to be done,
01547   after frontend implement necessary routines.
01548 */
01549 void ss_decl2pi::visit_ss_object_declaration(ptr< ss_object_declaration > x){entry("objdecl");
01550 
01551         //TODO 
01552         //      * static & local extern - they have to be allocated in global scope
01553         //              and also their destructor 
01554         //      * constructors and destructors lookup have to be done later
01555         //      * initializations by constant expressions (int i=3+5;)
01556         //      * binding references
01557         //      * int A=f(x) has to be handled especially on namespace scope as described in ABI.
01558 
01559         ptr<pi_mem_factory> var_mem;
01560                 
01561         ptr<mem_alloc_manager> allocator = mem_alloc_manager::instance();
01562         
01563         if (caller->current_function_get()) {           //local scope   //&TODO local extern allocate as global var
01564                 
01565                 var_mem = allocator->allocate_local_var(caller->current_function_get(),x);
01566                 
01567                 if (statement->initializer_kind_get() == ss_decl_stmt::IK_COPY_INITIALIZATION){         //int i=f(x);
01568                         entry("local copy init");
01569         
01570                         ptr< ss_expression > expr_temp = statement->args_get()->front(); 
01571                         start_ss_expr2pi(statement,caller);
01572                         ptr< pi_preg > res = expr_visitor->returns_preg(expr_temp);     //sideeffect evaluation is not enough, we need to know result of the whole expression
01573                 
01574                         ptr< pi_mem > dest = var_mem->get_mem(ss_sp2pi_sp(statement->psp_get()));
01575                 
01576                         lassert2(res,"initialization operand incorrect.");
01577                 
01578                         lint level = 1+max (                                            //get level for current pseudoinstruction
01579                                 max( statement->psp_get()->level_get(), statement->nsp_get()->level_get() ),
01580                                 res->origin_get()->level_get()
01581                                 );
01582                 
01583                         ptr< pi_st > tmp = pi_st::create(                                       //store equivalent to assignemnt
01584                                 ss_sp2pi_sp(statement->psp_get()),
01585                                 ss_sp2pi_sp(statement->nsp_get()),
01586                                 level,
01587                                 dest,
01588                                 res,
01589                                 ss_type2tm_type_convertor::instance()->convert(x->type_get())
01590                                 );
01591                 
01592                         backend_data_builder::instance()->add_pi(tmp);
01593                         temporaries->back_roll_table(ss_sp2pi_sp(statement->nsp_get()),ss_sp2pi_sp(statement->nsp_get()->nsp_get()));   //Temporaries destructors will be made between statement sequence points
01594 
01595                         outry("local copy init");
01596                  } //copy init
01597 
01598         
01599          } //local scope
01600          else                   //namespace scope
01601                 {       
01602                         //zero intialization is automatical 
01603                         
01604                         var_mem = allocator->allocate_global_var(x);
01605                 
01606                         if (statement->initializer_kind_get() == ss_decl_stmt::IK_COPY_INITIALIZATION){         //int i=3; 
01607                                 entry("global copy init");
01608                 
01609                 
01610                 // this hack is to be removed, when initialization by constant expressions and function is implemented
01611                                 ptr< ss_expression > expr_init = statement->args_get()->front(); 
01612                                 if(expr_init && !(dynamic_cast <ss_literal *>(expr_init.operator->()))) {
01613                                         lassert2(false,"This kind of initialization on namespace scope is not implemented now.");
01614                                 }
01615         
01616         
01617                                 ptr < ss_linfo2pi_linfo > cnv = ss_linfo2pi_linfo::create();
01618                 
01619                                 ptr< ss_expression > expr_temp = statement->args_get()->front(); 
01620                                 ptr< ss_literal > lit_temp = expr_temp.dncast<ss_literal>();
01621                                 ptr< literal_info_base > pinfo = cnv->get_pinfo(lit_temp->value_get()); 
01622         
01623                                 allocator->init_global_var(var_mem,pinfo);
01624                                 outry("global copy init");
01625                         }
01626                 } //local scope 
01627 
01628         
01629         if (statement->initializer_kind_get() == ss_decl_stmt::IK_DIRECT_INITIALIZATION){       //int i(3);
01630                 lassert2(false,"Direct initializations are not implemented now");
01631          }
01632 
01633         if (statement->initializer_kind_get() == ss_decl_stmt::IK_DEFAULT_INITIALIZATION){      //int i;        
01634                 //TODO for classes constructor shall be calleda
01635          }
01636          
01637         caller->mem_variable_set(x,var_mem);                    //new memory allocated for variable //TODO local extern
01638         ss_destructor_tables::instance()->destructor_add(x->type_get(),var_mem);
01639 
01640 outry("objdecl");
01641 }
01642 
01643 /*!
01644   VMT for classes should be done here, when classes will be implemented.
01645 */
01646 void ss_decl2pi::visit_ss_structure_declaration(ptr< ss_structure_declaration > ){
01647         lassert2(false,"Class support is not implemented now in ss2pi.");
01648 }
01649 
01650 
01651 void ss_decl2pi::default_action(ptr< ss_declaration > ){                //other declaration are not important
01652         return;
01653 }
01654 
01655 
01656 
01657 /////////////////////////////////////           Real declaration lookup                 ///////////////////
01658 
01659 /*!
01660   Function parameter cant be obtained from ss_decl_statement as normal variables.
01661 */
01662 void ss_decl2mem::visit_ss_parameter_declaration(ptr< ss_parameter_declaration > x){entry("lookup param decl");
01663           
01664           result = function_parameter_accessor::instance(caller->current_function_get())->get_parameter(x->position_get());
01665           
01666 outry("lookup param decl");
01667 }
01668 
01669 /*!
01670   Fake declarations are ignored, real declaration is important.
01671 */
01672 void ss_decl2mem::visit_ss_fake_declaration(ptr< ss_fake_declaration > x){entry("lookup fake decl");
01673 
01674         this->get_real_decl_mem(x->real_decl_get());            //no result needed, it remains the same
01675         
01676 outry("lookup fake decl");
01677 }
01678 
01679 /*!
01680   Usually variable overriden by fake in case of "if" statement. 
01681   pi_mem_factory will be already in map.
01682 */
01683 void ss_decl2mem::visit_ss_object_declaration(ptr< ss_object_declaration > x){entry("lookup object decl");
01684 
01685         result = caller->mem_variable_get(x);
01686 
01687 outry("lookup object decl");
01688 }
01689 
01690 
01691 void ss_decl2mem::default_action(ptr< ss_declaration >){
01692         result=NULL;
01693 }
01694 
01695 ///////////////////////////             TYPE  ->  Destructor    ////////////////////////////////
01696 
01697 
01698 void ss_type2destructor::default_destructor(ptr< ::lestes::lang::cplus::sem::ss_type > ){
01699         destructor = NULL;      //builtin types have no destructors
01700 }
01701 
01702 void ss_type2destructor::visit_ss_class(ptr< ::lestes::lang::cplus::sem::ss_class > x){
01703         destructor = ss_destructor_finder::instance()->find_default_destructor (x);
01704 }
01705 
01706 /*!
01707   Unions also have constructors and destructors [9.5/1]
01708 */
01709 void ss_type2destructor::visit_ss_union(ptr< ::lestes::lang::cplus::sem::ss_union > ){
01710 //TODO
01711 }
01712 
01713 /////////////////////////               Destructor Tables               ////////////////////////////////
01714 
01715 
01716 
01717 /*!
01718   Adds destructor to destructor table.
01719   It expect appropriate destructor to memmory placeholder (namely NULL for builtin types).
01720 */
01721 void ss_destructor_table::destructor_add(ptr< ss_function_declaration > x , ptr< ::lestes::backend_v2::intercode::pi_mem_factory > y ){
01722         plog(dtl) << "Table " << this->uid_get()<< " : added "<< y->uid_get() << "\n";
01723         destructors->push_back(destructor_entry_type::create(x,y));
01724 }
01725 
01726 /*!
01727   Basic interface to get handle for destructor tables of the current translatioon unit.
01728   Internal fields of destructor tables are static. They shall be initialized by open_compound_stmt method.
01729 */
01730 ptr< ss_destructor_tables > ss_destructor_tables::instance(){
01731         if ( !singleton_instance_get() ) {
01732                 singleton_instance_set(ss_destructor_tables_stack::create());
01733         }
01734         return singleton_instance_get();
01735 }
01736 
01737 /*!
01738   Open new destructor table for newly entered compound statement and insert it into destructor_tables structure.
01739 */
01740 ptr< ss_destructor_table > ss_destructor_tables_stack::open_compound_stmt(ptr< ss_compound_stmt > x){
01741         ptr< ss_destructor_table > tmp = ss_destructor_table::create(x);
01742         plog(dtl) << "Opening Scope Table " << tmp->uid_get()<<"\n" << eolog;
01743         
01744         tables->push_back(tmp);
01745         current = tmp;
01746         return tmp;
01747 }
01748 
01749 /*!
01750   Close destructor table of compound statement and return table for now.
01751 */
01752 ptr< ss_destructor_table > ss_destructor_tables_stack::close_compound_stmt(){
01753 
01754         lassert2(!tables->empty(),"There is no destructor table left to be removed.");
01755         plog(dtl) << "Closing Scope Table " << tables->back()->uid_get()<<"\n" << eolog;
01756 
01757         tables->pop_back();
01758         current = tables->back();
01759         if (tables->empty()) return NULL;               //occurs in a case of closing global compound statement
01760         return tables->back();
01761 }
01762 
01763 /*!
01764   Find and record destructor for ss type, which destructs appropriate memory placeholder.
01765   Such a record will be added to a given destructor table.
01766 */
01767 void ss_destructor_tables_stack::destructor_add_to_destr(ptr< ss_destructor_table >destr, ptr< ss_type > type , ptr< ::lestes::backend_v2::intercode::pi_mem_factory > var ){
01768 
01769         destr -> destructor_add ( ss_type2destructor::create()->find_destructor(type) , var );
01770 }
01771 
01772 /*!
01773   Find and record destructor for ss type, which destructs appropriate memory placeholder.
01774   Such a record will be added to current destructor table.
01775 */
01776 void ss_destructor_tables_stack::destructor_add(ptr< ss_type > type , ptr< ::lestes::backend_v2::intercode::pi_mem_factory > var ){
01777 
01778         destructor_add_to_destr (current, type , var );
01779 }
01780 
01781 /*!
01782   Implements back rolling of a given destructor table (i.e. usually compound statement).
01783   Accepts pseudoinstruction sequence points, between which pastes destructor calls
01784   and dealocation routines. psp and nsp of a given sequence points will change.
01785   
01786   Returns last sequence point, which has nsp set to nsp argument of function. 
01787   (i.e. there is no instruction between returned sp and given psp)
01788   So than can be recursive continuation in other compound statements.
01789 */
01790 ptr< ::lestes::backend_v2::intercode::pi_sp > ss_destructor_table::back_roll_table(ptr< ::lestes::backend_v2::intercode::pi_sp > psp, ptr< ::lestes::backend_v2::intercode::pi_sp > nsp){
01791 plog(dtl) << "table back roll " << this->uid_get()<<" [ psp: "<<psp->uid_get()<< " nsp: " <<nsp->uid_get()<<"]\n" <<eolog;; 
01792 
01793         ptr< pi_sp > last_sp = psp;
01794         list < srp < destructor_entry_type > >::reverse_iterator i = this->destructors_get()->rbegin();
01795         for(; i != this->destructors_get()->rend() ; i++ ){
01796                 
01797                 ptr< pi_sp > new_sp = pi_sp::create (last_sp,nsp,nsp->level_get());
01798                 last_sp->nsp_set(new_sp);
01799                 backend_data_builder::instance()->add_sp(new_sp);
01800 
01801                 if ((*i)->first){                       //exists destructor function
01802                         //TODO  when classes are implemented, destructor shall be called here
01803                 }//if
01804                 
01805                 plog(dtl) << "Table " << this->uid_get() << " : destruct " << (*i)->second->uid_get() <<"\n";
01806                 plog(spl) << "  SP: destr pi_sp added : " <<new_sp->uid_get() << "\n" <<eolog;
01807         
01808                 mem_alloc_manager::instance()->deallocate((*i)->second,last_sp,new_sp);
01809                 last_sp=new_sp;
01810         }//for
01811         
01812         last_sp->nsp_set(nsp);
01813         nsp->psp_set(last_sp);
01814         return last_sp;
01815 }
01816 
01817 /*!
01818   Normal end of compound statement.
01819   back_roll_table shall be called. Also appropriate sequence points have to be tranformed into 
01820   pseudoinstruction sequence points. (this transformation has to be done before new nested pi-sp
01821   will be added.
01822 */
01823 void ss_destructor_tables_stack::back_roll_from_current_compound_stmt(){
01824 plog(dtl) << "From current compound";
01825         current->back_roll_table(
01826                         ss_sp2pi_sp(current->compound_stmt_get()->destructor_sp_get()),
01827                         ss_sp2pi_sp(current->compound_stmt_get()->nsp_get())
01828                         );
01829 }
01830 
01831 /*!
01832   Abnormal end of compound statement; psp,nsp shall be taken from current return statement.
01833   This function requires that the whole destructor_tables structure begin with compound statement
01834   representing global namespace.
01835 */
01836 void ss_destructor_tables_stack::back_roll_from_function(ptr< pi_sp > psp, ptr< pi_sp > nsp){
01837 plog(dtl) << "From function ";
01838 
01839         back_roll_to_compound_stmt(ss_compound_stmt::root_instance(),false,psp,nsp);
01840 }
01841 
01842 /*!
01843   Abnormal end of compound statement; psp,nsp shall be taken from current statement(e.g. break, continue, goto).
01844   Builds destructors for all the variablefrom current compound statement to compound statement given(inclusive
01845   if inclusive set to true).  
01846 */
01847 void ss_destructor_tables_stack::back_roll_to_compound_stmt(ptr< ss_compound_stmt > stmt, bool inclusive, ptr< pi_sp > psp, ptr< pi_sp > nsp){
01848 plog(dtl) << "To compound";     
01849         lassert2(!tables->empty(),"Trying destructor back_roll in empty destructor tables.");
01850 
01851         ptr< pi_sp > last_sp = psp;
01852         ptr< pi_sp > end_sp = nsp;
01853         
01854         list < srp < ss_destructor_table > >::reverse_iterator i = tables->rbegin();
01855         do {
01856                 if (!inclusive) if(stmt == (*i)->compound_stmt_get() ) break;   //if exclusive do not back_roll the last record
01857                 last_sp=(*i)->back_roll_table(last_sp,end_sp);
01858         } while((*i++)->compound_stmt_get() != stmt);           //while in function/while
01859 
01860 }
01861         
01862 
01863 /*!
01864   Visitor for converting ss integral literals into pi literals.
01865   Structure for ss and pi are similar, thus simple conversion is possible.
01866 */
01867 void ss_linfo2pi_linfo::visit_ss_integral_literal_info(ptr< ss_integral_literal_info > x){
01868         
01869         pinfo = li_simple::create (
01870                         ss_type2tm_type_convertor::instance()->convert(x->type_get()),
01871                         x->data_get()); 
01872 }
01873 
01874 /*!
01875   Visitor for converting ss floating literals into pi literals.
01876   Up to now, backend doesnt provide floating point literal info,
01877   thus no conversion is possible.
01878 */
01879 void ss_linfo2pi_linfo::visit_ss_floating_literal_info(ptr< ss_floating_literal_info >){
01880         lassert2(false, "Floating point literal conversion to backend structures is not implemented.");
01881 }
01882 
01883 
01884 /*!
01885   Visitor for converting ss compound literals into pi literals.
01886   Structure for ss and pi are similar, thus simple conversion is possible.
01887 */
01888 void ss_linfo2pi_linfo::visit_ss_compound_literal_info(ptr < ss_compound_literal_info > x){
01889 
01890         ptr< ss_linfo2pi_linfo > cnv = ss_linfo2pi_linfo::create();
01891 
01892         ptr< list< srp< literal_info_base > > > atoms = list< srp< literal_info_base > >::create();  
01893         
01894         list < srp < ss_literal_info > >::iterator i = x->constituents_get()->begin();
01895         for(; i != x->constituents_get()->end() ; i++ )         
01896                 atoms->push_back(cnv->get_pinfo(*i));
01897 
01898         pinfo = li_compound::create (
01899                         ss_type2tm_type_convertor::instance()->convert(x->type_get()),
01900                         atoms
01901                 );
01902                 
01903 }
01904 
01905 end_package(sem);
01906 end_package(cplus);
01907 end_package(lang);
01908 end_package(lestes);

Generated on Mon Feb 12 18:23:29 2007 for lestes by doxygen 1.5.1-20070107