or_or.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 /*! \file
00029  * This file contains implementation of visitor on ss_decl_name. This is used
00030  * to determine, if the operator we are currenlty processing is builtin
00031  * operator, conversion function, or "ordinary" function.
00032  *
00033  * Also, this file contains overloaded operator() of or_or_functional, which
00034  * is used to construct proper ss_expression.
00035  *
00036  * \author jikos
00037  */
00038 
00039 #include <lestes/lang/cplus/sem/or_visitor.v.g.hh>
00040 #include <lestes/lang/cplus/sem/ss_decl_name.g.hh>
00041 #include <lestes/lang/cplus/sem/ss_declaration.g.hh>
00042 #include <lestes/lang/cplus/sem/ss_decl_name_visitor.v.g.hh>
00043 #include <lestes/lang/cplus/sem/ss_declaration_visitor.v.g.hh>
00044 #include <lestes/lang/cplus/sem/or_or.g.hh>
00045 #include <lestes/lang/cplus/sem/or_or.m.hh>
00046 #include <lestes/lang/cplus/sem/sa_deconstruct_spse.m.hh>
00047 #include <lestes/lang/cplus/sem/sa_deconstruct_spse.g.hh>
00048 #include <lestes/lang/cplus/sem/sa_statements.g.hh>
00049 #include <lestes/md/types/ss_type_size_evaluator.g.hh>
00050 #include <lestes/std/source_location.hh>
00051 #include <lestes/lang/cplus/sem/or_ics.g.hh>
00052 #include <lestes/lang/cplus/sem/ss_type.g.hh>
00053 #include <lestes/lang/cplus/sem/or_ics_actual_visitors.g.hh>
00054 #include <lestes/std/source_location.hh>
00055 #include <lestes/lang/cplus/sem/ss_literal_info.g.hh>
00056 
00057 package(lestes);
00058 package(lang);
00059 package(cplus);
00060 package(sem);
00061 
00062 using namespace ::lestes::md::types;
00063 
00064 #define IS_VOLATILE(x) (((x) == OR_CV_VOLATILE) || (x) == OR_CV_CONST_VOLATILE)
00065 class ss_function;
00066 /*!
00067  * This template covers operators which have form of binary op without sideeffect for arithmetics
00068  * This function takes the arguments to the operator from it's environment (the containing class'
00069  * fields) and constructs the ss_expression, the type of which is given by the template
00070  * argument.
00071  * SS - ss expression corresponding to the particular operator
00072  */
00073 template <typename SS> void or_builtin_operator_expression_creator::construct_bin_op_nosideeff_arith()
00074 {
00075         ptr< or_or_functional > l, r;
00076         ptr< ss_expression > l_expr, r_expr;
00077         ptr< ::lestes::std::source_location > loc = location_get();
00078         ::lestes::std::list< srp< or_or_functional > >::iterator it = arguments_get()->begin();
00079         ptr< or_ics_functional > l_func, r_func; 
00080         ::lestes::std::list< srp< ss_type > >::iterator it_p = declaration_get()->type_get().template dncast <ss_function>()->params_get()->begin();
00081         ptr< ss_expression > sizeof_mul_expr;
00082         bool was_ptr = false;
00083         bool multiplied_left = false;
00084         bool multiplied_right = false;
00085         
00086         l = *it;
00087         it++;
00088         r = (*it);
00089 
00090         /* find implicit conversion between argument and function parameter types */    
00091 
00092         /* If (one of) the arguments are not pointers, we must convert them both to the type of return value, as this is what ss2pi expects.
00093          * This is exactly what the following voodoo does.
00094          */
00095         ptr< or_ics_visitor_cv > v = or_ics_visitor_cv::create();
00096         
00097         /* If one of the arguments is pointer, then we are performing pointer arithmetics */
00098         if( ((l->type_get()->accept_or_ics_base_cv(v) == OR_CV_PTR || 
00099                                         (l->type_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE && 
00100                                          l->type_get().template dncast<ss_pseudoreference>()->what_get()->accept_or_ics_base_cv(v) == OR_CV_PTR))) ||
00101              ((r->type_get()->accept_or_ics_base_cv(v) == OR_CV_PTR || 
00102                                         (r->type_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE && 
00103                                          r->type_get().template dncast<ss_pseudoreference>()->what_get()->accept_or_ics_base_cv(v) == OR_CV_PTR)))) {
00104 
00105                 was_ptr = true; 
00106                 it = arguments_get()->begin();
00107                 l_func = or_find_ics(l, *it_p);
00108                 if (!l_func) {
00109                         report << incompatible_types_conversion << loc;
00110                         exit(1);
00111                 }       
00112 
00113                 it_p++;
00114                 r_func = or_find_ics(r, *(it_p));
00115                 if (!r_func) {
00116                         report << incompatible_types_conversion << loc;
00117                         exit(1);
00118                 }       
00119 
00120         } else { 
00121                 /* we have to convert both parameters to the type of return function */
00122                 ptr< or_ics_visitor_cv > v0 = or_ics_visitor_cv::create();
00123                 if(declaration_get()->type_get().template dncast <ss_function>()->returns_get()->accept_or_ics_base_cv(v0) == OR_CV_PSEUDOREFERENCE) {
00124                         l_func = or_find_ics(l, declaration_get()->type_get().template dncast <ss_function>()->returns_get().template dncast<ss_pseudoreference>()->what_get());
00125                         if (!l_func) {
00126                                 report << incompatible_types_conversion << loc;
00127                                 exit(1);
00128                         }       
00129 
00130                 }
00131                 else if (declaration_get()->type_get().template dncast <ss_function>()->returns_get()->accept_or_ics_base_cv(v0) == OR_CV_REFERENCE) {
00132                         l_func = or_find_ics(l, declaration_get()->type_get().template dncast <ss_function>()->returns_get().template dncast<ss_reference>()->what_get());
00133                         if (!l_func) {
00134                                 report << incompatible_types_conversion << loc;
00135                                 exit(1);
00136                         }       
00137 
00138                 }
00139                 
00140                 else { 
00141                         l_func = or_find_ics(l, declaration_get()->type_get().template dncast <ss_function>()->returns_get());
00142                         if (!l_func) {
00143                                 report << incompatible_types_conversion << loc;
00144                                 exit(1);
00145                         }       
00146 
00147                 }
00148 
00149                 ptr< or_ics_visitor_cv > v1 = or_ics_visitor_cv::create();
00150                 if(declaration_get()->type_get().template dncast <ss_function>()->returns_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE) {
00151                         r_func = or_find_ics(r, declaration_get()->type_get().template dncast <ss_function>()->returns_get().template dncast<ss_pseudoreference>()->what_get());
00152                         if (!r_func) {
00153                                 report << incompatible_types_conversion << loc;
00154                                 exit(1);
00155                         }       
00156 
00157                 }
00158                 else if(declaration_get()->type_get().template dncast <ss_function>()->returns_get()->accept_or_ics_base_cv(v) == OR_CV_REFERENCE) {
00159                         r_func = or_find_ics(r, declaration_get()->type_get().template dncast <ss_function>()->returns_get().template dncast<ss_reference>()->what_get());
00160                         if (!r_func) {
00161                                 report << incompatible_types_conversion << loc;
00162                                 exit(1);
00163                         }       
00164 
00165                 } else {
00166                         r_func = or_find_ics(r, declaration_get()->type_get().template dncast <ss_function>()->returns_get());
00167                         if (!r_func) {
00168                                 report << incompatible_types_conversion << loc;
00169                                 exit(1);
00170                         }       
00171 
00172                 }
00173 
00174         }
00175         /* this constructs the actual ss_expression for parameters, taking in account conversion sequences needed */
00176         l_expr = (*l_func)((*l)(psp_get(), nsp_get(), loc, sp_list_get()), psp_get(), nsp_get());
00177         r_expr = (*r_func)((*r)(psp_get(), nsp_get(), loc, sp_list_get()), psp_get(), nsp_get());
00178 
00179         /* We have to check now if we are performing pointer arithmetics. If so, we need to create another multiplying expression, which
00180          * will multiply the 'integral side' of the expression by the sizeof() of pointer's underlying type.
00181          *
00182          * Even the left one can be integral, as constant -+ ptr is allowed
00183          */
00184         if (was_ptr && (l->type_get()->accept_or_ics_base_cv(v) == OR_CV_SINT)) {
00185                 multiplied_left = true;
00186         
00187                 if (r->type_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE)
00188                         sizeof_mul_expr =  ss_conversion::create(       loc, 
00189                                                                 r->type_get().template dncast<ss_pseudoreference>()->what_get(),
00190                                                                 psp_get(),
00191                                                                 nsp_get(),
00192                                                                 ss_mul::create( loc, 
00193                                                                         ss_type_sint::instance(), 
00194                                                                         psp_get(), 
00195                                                                         nsp_get(), 
00196                                                                         l_expr, 
00197                                                                         ss_literal::create(
00198                                                                                         location, 
00199                                                                                         ss_type_sint::instance(), 
00200                                                                                         psp_get(), nsp_get(), 
00201                                                                                         ss_integral_literal_info::create_from_number(
00202                                                                                                         ss_type_uint::instance(), 
00203                                                                                         /* FIXME this has to neccessairly to be pseudoreference! */
00204                                                                                                         ss_type_size_evaluator::instance()->size_get(r->type_get().template dncast<ss_pseudoreference>()->what_get().template dncast<ss_pointer>()->what_get())/8))),
00205                                                                 ss_type_sint::instance()
00206                                                 );
00207                 else
00208                         sizeof_mul_expr =  ss_conversion::create(       loc, 
00209                                                                 r->type_get().template dncast<ss_reference>()->what_get(),
00210                                                                 psp_get(),
00211                                                                 nsp_get(),
00212                                                                 ss_mul::create( loc, 
00213                                                                         ss_type_sint::instance(), 
00214                                                                         psp_get(), 
00215                                                                         nsp_get(), 
00216                                                                         l_expr, 
00217                                                                         ss_literal::create(
00218                                                                                         location, 
00219                                                                                         ss_type_sint::instance(), 
00220                                                                                         psp_get(), nsp_get(), 
00221                                                                                         ss_integral_literal_info::create_from_number(
00222                                                                                                         ss_type_uint::instance(), 
00223                                                                                         /* FIXME this has to neccessairly to be pseudoreference! */
00224                                                                                                         ss_type_size_evaluator::instance()->size_get(r->type_get().template dncast<ss_pseudoreference>()->what_get().template dncast<ss_pointer>()->what_get())/8))),
00225                                                                 ss_type_sint::instance()
00226                                                 );
00227                         
00228 
00229         } else if (was_ptr && (r->type_get()->accept_or_ics_base_cv(v) == OR_CV_SINT)) {
00230                 multiplied_right = true;
00231                 if (l->type_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE) 
00232                         sizeof_mul_expr = ss_conversion::create(        loc,
00233                                                                 l->type_get().template dncast<ss_pseudoreference>()->what_get(),
00234                                                                 psp_get(),
00235                                                                 nsp_get(),
00236                                                                 ss_mul::create( loc, 
00237                                                                                 ss_type_sint::instance(), 
00238                                                                                 psp_get(), 
00239                                                                                 nsp_get(), 
00240                                                                                 r_expr, 
00241                                                                                 ss_literal::create(
00242                                                                                         location, 
00243                                                                                         ss_type_sint::instance(), 
00244                                                                                         psp_get(), nsp_get(), 
00245                                                                                         ss_integral_literal_info::create_from_number(
00246                                                                                                         ss_type_uint::instance(), 
00247                                                                                                 /* FIXME this has to neccessairly to be pseudoreference! */
00248                                                                                                         ss_type_size_evaluator::instance()->size_get(l->type_get().template dncast<ss_pseudoreference>()->what_get().template dncast<ss_pointer>()->what_get())/8))),
00249                                                                 ss_type_sint::instance()
00250                                                 );
00251                 else
00252                         sizeof_mul_expr = ss_conversion::create(        loc,
00253                                                                 l->type_get().template dncast<ss_reference>()->what_get(),
00254                                                                 psp_get(),
00255                                                                 nsp_get(),
00256                                                                 ss_mul::create( loc, 
00257                                                                                 ss_type_sint::instance(), 
00258                                                                                 psp_get(), 
00259                                                                                 nsp_get(), 
00260                                                                                 r_expr, 
00261                                                                                 ss_literal::create(
00262                                                                                         location, 
00263                                                                                         ss_type_sint::instance(), 
00264                                                                                         psp_get(), nsp_get(), 
00265                                                                                         ss_integral_literal_info::create_from_number(
00266                                                                                                         ss_type_uint::instance(), 
00267                                                                                                 /* FIXME this has to neccessairly to be pseudoreference! */
00268                                                                                                         ss_type_size_evaluator::instance()->size_get(l->type_get().template dncast<ss_pseudoreference>()->what_get().template dncast<ss_pointer>()->what_get())/8))),
00269                                                                 ss_type_sint::instance()
00270                                                 );
00271                         
00272         }
00273         /* If we performed pointer arithmetics, connect the ss_mul operation for sizeof() correctly */
00274         if (!multiplied_left && !multiplied_right)
00275                 if (l_expr->type_get()->accept_or_ics_base_cv(v) == OR_CV_PTR && r_expr->type_get()->accept_or_ics_base_cv(v) == OR_CV_PTR) 
00276                         /* the ptr - ptr case */
00277                         result_set(ss_conversion::create(loc,
00278                                                         ss_type_sint::instance(),
00279                                                         psp_get(),
00280                                                         nsp_get(),
00281                                                         SS::create(     loc, 
00282                                                                         l_expr->type_get(), 
00283                                                                         psp_get(), 
00284                                                                         nsp_get(), 
00285                                                                         l_expr, 
00286                                                                         r_expr),
00287                                                         l_expr->type_get()));
00288                 else
00289                         result_set(SS::create(  loc, 
00290                                         declaration_get()->type_get().template dncast<ss_function>()->returns_get(), 
00291                                         psp_get(), 
00292                                         nsp_get(), 
00293                                         l_expr, 
00294                                         r_expr));
00295         else if (multiplied_left)
00296                 result_set(SS::create(  loc, 
00297                                 declaration_get()->type_get().template dncast<ss_function>()->returns_get(), 
00298                                 psp_get(), 
00299                                 nsp_get(), 
00300                                 sizeof_mul_expr, 
00301                                 r_expr));
00302         else
00303                 result_set(SS::create(  loc, 
00304                                 declaration_get()->type_get().template dncast<ss_function>()->returns_get(), 
00305                                 psp_get(), 
00306                                 nsp_get(), 
00307                                 l_expr, 
00308                                 sizeof_mul_expr));
00309 
00310 }
00311 
00312 /*!
00313  * This template covers operators which have form of binary op without sideeffect which are non-arithmetic
00314  * This function takes the arguments to the operator from it's environment (the containing class'
00315  * fields) and constructs the ss_expression, the type of which is given by the template
00316  * argument.
00317  * SS - ss expression corresponding to the particular operator
00318  */
00319 template <typename SS> void or_builtin_operator_expression_creator::construct_bin_op_nosideeff()
00320 {
00321         ptr< or_or_functional > l, r;
00322         ptr< ss_expression > l_expr, r_expr;
00323         ptr< ::lestes::std::source_location > loc = location_get();
00324         ::lestes::std::list< srp< or_or_functional > >::iterator it = arguments_get()->begin();
00325         ptr< or_ics_functional > l_func, r_func; 
00326         ::lestes::std::list< srp< ss_type > >::iterator it_p = declaration_get()->type_get().template dncast <ss_function>()->params_get()->begin();
00327 
00328         l = *it;
00329         it++;
00330         r = (*it);
00331 
00332         /* find implicit conversion between argument and function parameter types */    
00333 
00334         /* If (one of) the arguments are not pointers, we must convert them both to the type of return value, as this is what ss2pi expects.
00335          * This is exactly what the following voodoo does.
00336          */
00337         ptr< or_ics_visitor_cv > v = or_ics_visitor_cv::create();
00338         
00339         /* If one of the arguments is pointer, then we are performing pointer arithmetics */
00340         if( ((l->type_get()->accept_or_ics_base_cv(v) == OR_CV_PTR || 
00341                                         (l->type_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE && 
00342                                          l->type_get().template dncast<ss_pseudoreference>()->what_get()->accept_or_ics_base_cv(v) == OR_CV_PTR))) ||
00343              ((r->type_get()->accept_or_ics_base_cv(v) == OR_CV_PTR || 
00344                                         (r->type_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE && 
00345                                          r->type_get().template dncast<ss_pseudoreference>()->what_get()->accept_or_ics_base_cv(v) == OR_CV_PTR))))             {
00346                 it = arguments_get()->begin();
00347                 l_func = or_find_ics(l, *it_p);
00348                 if (!l_func) {
00349                         report << incompatible_types_conversion << loc;
00350                         exit(1);
00351                 }       
00352 
00353                 it_p++;
00354                 r_func = or_find_ics(r, *(it_p));
00355                 if (!r_func) {
00356                         report << incompatible_types_conversion << loc;
00357                         exit(1);
00358                 }       
00359 
00360         } else { 
00361                 ptr< or_ics_visitor_cv > v0 = or_ics_visitor_cv::create();
00362                 if(r->type_get()->accept_or_ics_base_cv(v0) == OR_CV_PSEUDOREFERENCE) {
00363                         l_func = or_find_ics(l, r->type_get().template dncast<ss_pseudoreference>()->what_get());
00364                         if (!l_func) {
00365                                 report << incompatible_types_conversion << loc;
00366                                 exit(1);
00367                         }       
00368 
00369                         r_func = or_find_ics(r, r->type_get().template dncast<ss_pseudoreference>()->what_get());
00370                         if (!r_func) {
00371                                 report << incompatible_types_conversion << loc;
00372                                 exit(1);
00373                         }       
00374 
00375 
00376                 }
00377                 else {
00378                         l_func = or_find_ics(l, r->type_get());
00379                         if (!l_func) {
00380                                 report << incompatible_types_conversion << loc;
00381                                 exit(1);
00382                         }       
00383 
00384                         r_func = or_find_ics(r, r->type_get());
00385                         if (!r_func) {
00386                                 report << incompatible_types_conversion << loc;
00387                                 exit(1);
00388                         }       
00389 
00390                 }
00391 
00392         }
00393         /* this constructs the actual ss_expression for parameters, taking in account conversion sequences needed */
00394         l_expr = (*l_func)((*l)(psp_get(), nsp_get(), loc, sp_list_get()), psp_get(), nsp_get());
00395         r_expr = (*r_func)((*r)(psp_get(), nsp_get(), loc, sp_list_get()), psp_get(), nsp_get());
00396         
00397         result_set(SS::create(  loc, 
00398                                 declaration_get()->type_get().template dncast<ss_function>()->returns_get(), 
00399                                 psp_get(), 
00400                                 nsp_get(), 
00401                                 l_expr, 
00402                                 r_expr));
00403 
00404 }
00405 
00406 /*!
00407  * This template covers operators which have form of binary op without sideeffect, but there is 
00408  * need to create new sequence point (so this covers '||' and '&&' operators. The operator 
00409  * ',' is handled elsewhere, as there is no need to create new ss_expression).
00410  *
00411  * This function takes the arguments to the operator from it's environment (the containing class'
00412  * fields) and constructs the ss_expression, the type of which is given by the template
00413  * argument.
00414  * SS - ss expression corresponding to the particular operator
00415  */
00416 template <typename SS> void or_builtin_operator_expression_creator::construct_bin_op_nosideeff_newsp()
00417 {
00418         ptr< or_or_functional > l, r;
00419         ptr< ss_expression > l_expr, r_expr;
00420         ptr< ::lestes::std::source_location > loc = location_get();
00421         ::lestes::std::list< srp< or_or_functional > >::iterator it = arguments_get()->begin();
00422         ptr< or_ics_functional > l_func, r_func; 
00423         ::lestes::std::list< srp< ss_type > >::iterator it_p = declaration_get()->type_get().template dncast <ss_function>()->params_get()->begin();
00424 
00425         l = *it;
00426         it++;
00427         r = *(it);
00428 
00429         /* find implicit conversion between argument and function parameter types */    
00430         /* If (one of) the arguments are not pointers, we must convert them both to the type of
00431          * return value, as this is what ss2pi expects
00432          */
00433         ptr< or_ics_visitor_cv > v = or_ics_visitor_cv::create();
00434         if(l->type_get()->accept_or_ics_base_cv(v) != OR_CV_PTR) {
00435 
00436                 ptr< or_ics_visitor_cv > v0 = or_ics_visitor_cv::create();
00437                 if(declaration_get()->type_get().template dncast <ss_function>()->returns_get()->accept_or_ics_base_cv(v0) == OR_CV_PSEUDOREFERENCE){
00438                         l_func = or_find_ics(l, declaration_get()->type_get().template dncast <ss_function>()->returns_get().template dncast<ss_pseudoreference>()->what_get());
00439                         if (!l_func) {
00440                                 report << incompatible_types_conversion << loc;
00441                                 exit(1);
00442                         }       
00443 
00444                 }
00445                 else {
00446                         l_func = or_find_ics(l, declaration_get()->type_get().template dncast <ss_function>()->returns_get());
00447                         if (!l_func) {
00448                                 report << incompatible_types_conversion << loc;
00449                                 exit(1);
00450                         }       
00451 
00452                 }
00453 
00454                 ptr< or_ics_visitor_cv > v1 = or_ics_visitor_cv::create();
00455                 if(declaration_get()->type_get().template dncast <ss_function>()->returns_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE) {
00456                         r_func = or_find_ics(r, declaration_get()->type_get().template dncast <ss_function>()->returns_get().template dncast<ss_pseudoreference>()->what_get());
00457                         if (!r_func) {
00458                                 report << incompatible_types_conversion << loc;
00459                                 exit(1);
00460                         }       
00461                 }
00462                 else {
00463                         r_func = or_find_ics(r, declaration_get()->type_get().template dncast <ss_function>()->returns_get());
00464                         if (!r_func) {
00465                                 report << incompatible_types_conversion << loc;
00466                                 exit(1);
00467                         }       
00468                 }
00469         } else {
00470                 it = arguments_get()->begin();
00471                 l_func = or_find_ics(l, *it_p);
00472                 if (!l_func) {
00473                         report << incompatible_types_conversion << loc;
00474                         exit(1);
00475                 }       
00476 
00477                 it_p++;
00478                 r_func = or_find_ics(r, *(it_p));
00479                 if (!r_func) {
00480                         report << incompatible_types_conversion << loc;
00481                         exit(1);
00482                 }       
00483 
00484         }
00485 
00486         /* this constructs the actual ss_expression for parameters, taking in account conversion sequences needed */
00487         l_expr = (*l_func)((*l)(psp_get(), nsp_get(), loc, sp_list_get()), psp_get(), nsp_get());
00488         r_expr = (*r_func)((*r)(psp_get(), nsp_get(), loc, sp_list_get()), psp_get(), nsp_get());
00489 
00490 
00491         result_set(SS::create(  loc, 
00492                                 declaration_get()->type_get().template dncast<ss_function>()->returns_get(), 
00493                                 psp_get(), 
00494                                 nsp_get(), 
00495                                 l_expr, 
00496                                 r_expr));
00497 
00498         /* create new sequence point and add to lists properly */
00499         lint level = MAX(psp_get()->level_get(), nsp_get()->level_get())+1;
00500         ptr< ss_sp > new_sp = ss_sp::create(loc, psp_get(), nsp_get(), level);
00501         sp_list_get()->push_back(new_sp);
00502 }
00503 
00504 /*!
00505  * This template covers operators which have form of unary op without sideeffect
00506  * This function takes the arguments to the operator from it's environment (the containing class'
00507  * fields) and constructs the ss_expression, the type of which is given by the template
00508  * argument.
00509  * SS - ss expression corresponding to the particular operator
00510  */
00511 template <typename SS> void or_builtin_operator_expression_creator::construct_un_op_nosideeff()
00512 {
00513         ptr< or_or_functional > l;
00514         ptr< ss_expression > l_expr;
00515         ptr< ::lestes::std::source_location > loc = location_get();
00516         ::lestes::std::list< srp< or_or_functional > >::iterator it = arguments_get()->begin();
00517         ptr< or_ics_functional > l_func; 
00518         ::lestes::std::list< srp< ss_type > >::iterator it_p = declaration_get()->type_get().template dncast <ss_function>()->params_get()->begin();
00519 
00520         l = *it;
00521 
00522         /* find implicit conversion between argument and function parameter types */    
00523         it = arguments_get()->begin();
00524         l_func = or_find_ics(l, *it_p);
00525         if (!l_func) {
00526                 report << incompatible_types_conversion << loc;
00527                 exit(1);
00528         }       
00529 
00530         
00531         /* this constructs the actual ss_expression for parameters, taking in account conversion sequences needed */
00532         l_expr = (*l_func)((*l)(psp_get(), nsp_get(), loc, sp_list_get()), psp_get(), nsp_get());
00533 
00534         result_set(SS::create(  loc, 
00535                                 declaration_get()->type_get().template dncast<ss_function>()->returns_get(), 
00536                                 psp_get(), 
00537                                 nsp_get(), 
00538                                 l_expr));
00539 }
00540 
00541 /*!
00542  * This template covers operators which have form of ++ or -- (prefix or postfix)
00543  *
00544  * This function takes the arguments to the operator from it's environment (the containing class'
00545  * fields) and constructs the ss_expression, the type of which is given by the template
00546  * argument.
00547  * Also, it inserts the newly created sideeffect to the sideeffect list of the guarding sequence
00548  * points.
00549  * SS - ss expression corresponding to the particular operator
00550  */
00551 template <typename SS> void or_builtin_operator_expression_creator::construct_op_crement()
00552 {
00553         ptr< ::lestes::std::source_location > loc = location_get();
00554         ptr< or_or_functional > l, rf;
00555         ptr < ss_expression > e, l_expr, get, r;
00556         ptr< ss_assign > p;
00557         ::lestes::std::list< srp< or_or_functional > >::iterator it = arguments_get()->begin();
00558         ::lestes::std::list< srp< or_or_functional > >::size_type num_args = arguments_get()->size();
00559         ptr< or_ics_visitor_cv > v = or_ics_visitor_cv::create();
00560         ptr< or_ics_functional > l_func, r_func; 
00561         ::lestes::std::list< srp< ss_type > >::iterator it_p = declaration_get()->type_get().template dncast <ss_function>()->params_get()->begin();
00562         ptr< ss_expression > literal_one;
00563 
00564         
00565         l = *it;
00566 
00567         ptr< or_ics_visitor_cv > v1 = or_ics_visitor_cv::create();
00568         if(l->type_get()->accept_or_ics_base_cv(v1) != OR_CV_PSEUDOREFERENCE && l->type_get()->accept_or_ics_base_cv(v1) != OR_CV_REFERENCE) {
00569                 report << non_lval_crement << loc;
00570                 exit(1);
00571         } 
00572 
00573         literal_one = ss_literal::create(loc, ss_type_sint::instance(), psp_get(), nsp_get(), ss_integral_literal_info::create_from_number(
00574                                                                             ss_type_sint::instance(), 1));
00575         
00576         /* find implicit conversion between argument and function parameter types */
00577         it = arguments_get()->begin();
00578 
00579         //l_func = or_find_ics(l, *it_p);
00580         /* The l parameter has to stay as it is for ss2pi to be happy - both types the same */
00581         l_func = or_ics_functional_for_std_conversion::create(RANK_EXACT, l->type_get());
00582 
00583         /* this constructs the actual ss_expression for parameters, taking in account conversion sequences needed */
00584         l_expr = (*l_func)((*l)(psp_get(), nsp_get(), loc, sp_list_get()), psp_get(), nsp_get());
00585 
00586         if (num_args == 1) {
00587                 /* argument r, representing literal '1' must be created for the postfix case (for the prefix case, the argument has already 
00588                  * been created in sa_deconstruct_spse.cc for the purpose of overload resolution
00589                  */
00590                 ptr< or_ics_visitor_cv > v = or_ics_visitor_cv::create();
00591 
00592                 /* If one of the arguments is pointer, then we are performing pointer arithmetics */
00593                 if( ((l->type_get()->accept_or_ics_base_cv(v) == OR_CV_PTR ||
00594                                                 (l->type_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE &&
00595                                                  l->type_get().template dncast<ss_pseudoreference>()->what_get()->accept_or_ics_base_cv(v) == OR_CV_PTR)))) {
00596                         ptr< ss_expression > r_;
00597                         /* This ugly code performs literal * literal for sizeof() and converts the result to pointer. backend wants it */
00598                         r_ = ss_literal::create(loc, ss_type_sint::instance(), psp_get(), nsp_get(), 
00599                                         ss_integral_literal_info::create_from_number(ss_type_sint::instance(), 
00600                                                 ss_type_size_evaluator::instance()->size_get(
00601                                                         l->type_get().template dncast<ss_pseudoreference>()->what_get().template dncast<ss_pointer>()->what_get())/8));
00602                         r = ss_conversion::create(      loc, 
00603                                                         l->type_get().template dncast<ss_pseudoreference>()->what_get(),
00604                                                         psp_get(),
00605                                                         nsp_get(),
00606                                                         ss_mul::create( loc, 
00607                                                                         ss_type_sint::instance(), 
00608                                                                         psp_get(), 
00609                                                                         nsp_get(), 
00610                                                                         literal_one,
00611                                                                         r_),
00612                                                         ss_type_sint::instance()
00613                                                 );
00614                         
00615                 } else if( ((l->type_get()->accept_or_ics_base_cv(v) == OR_CV_PTR ||
00616                                                 (l->type_get()->accept_or_ics_base_cv(v) == OR_CV_REFERENCE &&
00617                                                  l->type_get().template dncast<ss_reference>()->what_get()->accept_or_ics_base_cv(v) == OR_CV_PTR)))) {
00618                         ptr< ss_expression > r_;
00619                         /* This ugly code performs literal * literal for sizeof() and converts the result to pointer. backend wants it */
00620         
00621                         r_ = ss_literal::create(loc, ss_type_sint::instance(), psp_get(), nsp_get(), 
00622                                         ss_integral_literal_info::create_from_number(ss_type_sint::instance(), 
00623                                                 ss_type_size_evaluator::instance()->size_get(
00624                                                         l->type_get().template dncast<ss_reference>()->what_get().template dncast<ss_pointer>()->what_get())/8));
00625                         r = ss_conversion::create(      loc, 
00626                                                         l->type_get().template dncast<ss_reference>()->what_get(),
00627                                                         psp_get(),
00628                                                         nsp_get(),
00629                                                         ss_mul::create( loc, 
00630                                                                         ss_type_sint::instance(), 
00631                                                                         psp_get(), 
00632                                                                         nsp_get(), 
00633                                                                         literal_one,
00634                                                                         r_),
00635                                                         ss_type_sint::instance()
00636                                                 );
00637                         
00638         
00639                 } else {
00640                         if(l->type_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE)
00641                                 r = ss_literal::create(loc, ss_type_sint::instance(), psp_get(), nsp_get(), ss_integral_literal_info::create_from_number(
00642                                                 l->type_get().template dncast<ss_pseudoreference>()->what_get(), 1));
00643                         else
00644                                 r = ss_literal::create(loc, ss_type_sint::instance(), psp_get(), nsp_get(), ss_integral_literal_info::create_from_number(
00645                                                 l->type_get().template dncast<ss_reference>()->what_get(), 1));
00646                 }
00647         } else  /* num_args == 2 */
00648                 if( ((l->type_get()->accept_or_ics_base_cv(v) == OR_CV_PTR ||
00649                                                 (l->type_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE &&
00650                                                  l->type_get().template dncast<ss_pseudoreference>()->what_get()->accept_or_ics_base_cv(v) == OR_CV_PTR)))) {
00651                         ptr< ss_expression > r_;
00652                         /* This ugly code performs literal * literal for sizeof() and converts the result to pointer. backend wants it */
00653                         r_ = ss_literal::create(loc, ss_type_sint::instance(), psp_get(), nsp_get(), 
00654                                         ss_integral_literal_info::create_from_number(ss_type_sint::instance(), 
00655                                                 ss_type_size_evaluator::instance()->size_get(
00656                                                         l->type_get().template dncast<ss_pseudoreference>()->what_get().template dncast<ss_pointer>()->what_get())/8));
00657                         r = ss_conversion::create(      loc, 
00658                                                         l->type_get().template dncast<ss_pseudoreference>()->what_get(),
00659                                                         psp_get(),
00660                                                         nsp_get(),
00661                                                         ss_mul::create( loc, 
00662                                                                         ss_type_sint::instance(), 
00663                                                                         psp_get(), 
00664                                                                         nsp_get(), 
00665                                                                         literal_one,
00666                                                                         r_),
00667                                                         ss_type_sint::instance()
00668                                                 );
00669                 } else  if( ((l->type_get()->accept_or_ics_base_cv(v) == OR_CV_PTR ||
00670                                                 (l->type_get()->accept_or_ics_base_cv(v) == OR_CV_REFERENCE &&
00671                                                  l->type_get().template dncast<ss_reference>()->what_get()->accept_or_ics_base_cv(v) == OR_CV_PTR)))) {
00672                         ptr< ss_expression > r_;
00673                         /* This ugly code performs literal * literal for sizeof() and converts the result to pointer. backend wants it */
00674                         r_ = ss_literal::create(loc, ss_type_sint::instance(), psp_get(), nsp_get(), 
00675                                         ss_integral_literal_info::create_from_number(ss_type_sint::instance(), 
00676                                                 ss_type_size_evaluator::instance()->size_get(
00677                                                         l->type_get().template dncast<ss_reference>()->what_get().template dncast<ss_pointer>()->what_get())/8));
00678                         r = ss_conversion::create(      loc, 
00679                                                         l->type_get().template dncast<ss_reference>()->what_get(),
00680                                                         psp_get(),
00681                                                         nsp_get(),
00682                                                         ss_mul::create( loc, 
00683                                                                         ss_type_sint::instance(), 
00684                                                                         psp_get(), 
00685                                                                         nsp_get(), 
00686                                                                         literal_one,
00687                                                                         r_),
00688                                                         ss_type_sint::instance()
00689                                                 );
00690  
00691                 } else {
00692                         it++;
00693                         rf = (*it);
00694                         it_p++;
00695                         /* both types in assignment have to be the same */
00696                         /* If one of the arguments is pointer, then we are performing pointer arithmetics */
00697                         if(l->type_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE &&
00698                                 l->type_get().template dncast<ss_pseudoreference>()->what_get()->accept_or_ics_base_cv(v1) != OR_CV_PTR) {
00699                                         r_func = or_find_ics(rf, l->type_get().template dncast<ss_pseudoreference>()->what_get());
00700                                         if (!r_func) {
00701                                                 report << incompatible_types_conversion << loc;
00702                                                 exit(1);
00703                                         }       
00704                                 
00705                         } else if(l->type_get()->accept_or_ics_base_cv(v) == OR_CV_REFERENCE && 
00706                                 l->type_get().template dncast<ss_reference>()->what_get()->accept_or_ics_base_cv(v1) != OR_CV_PTR) {
00707                                         r_func = or_find_ics(rf, l->type_get().template dncast<ss_reference>()->what_get());
00708                                         if (!r_func) {
00709                                                 report << incompatible_types_conversion << loc;
00710                                                 exit(1);
00711                                         }       
00712                         } else {
00713                                 if (l->type_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE)
00714                                         r_func = or_ics_functional_for_std_conversion::create(RANK_EXACT, l->type_get().template dncast<ss_pseudoreference>()->what_get().template dncast<ss_pointer>()->what_get());
00715                                 else
00716                                         r_func = or_ics_functional_for_std_conversion::create(RANK_EXACT, l->type_get().template dncast<ss_reference>()->what_get().template dncast<ss_pointer>()->what_get());
00717                 }
00718                 /* this constructs the actual ss_expression for parameters, taking in account conversion sequences needed */
00719                 r = (*r_func)((*rf)(psp_get(), nsp_get(), loc, sp_list_get()), psp_get(), nsp_get());
00720         }
00721         
00722         /* volatile type should be handled in a different way */
00723         if(IS_VOLATILE(l->type_get()->accept_or_ics_base_cv(v))) {
00724                 get = ss_vol_get::create(loc, l_expr->type_get(), psp_get(), nsp_get(), l_expr);
00725                 ptr< ss_se > se = ss_se::create(loc, l_expr, psp_get(), nsp_get());
00726 
00727                 /* add newly created sideeffect into the lists */
00728                 psp_get()->nse_get()->push_back(se);
00729                 nsp_get()->pse_get()->push_back(se);
00730 
00731         } else {
00732                 ptr< or_ics_visitor_cv > v = or_ics_visitor_cv::create();
00733                 if(l->type_get()->accept_or_ics_base_cv(v) != OR_CV_PSEUDOREFERENCE && l->type_get()->accept_or_ics_base_cv(v) != OR_CV_REFERENCE) {
00734                         report << non_lval_crement << loc;
00735                         exit(1);
00736                 }
00737                 if (l->type_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE)
00738                         get = ss_get::create(loc, l->type_get().template dncast<ss_pseudoreference>()->what_get(), psp_get(), nsp_get(), l_expr);
00739                 else
00740                         get = ss_get::create(loc, l->type_get().template dncast<ss_reference>()->what_get(), psp_get(), nsp_get(), l_expr);
00741         }
00742 
00743         /* this creates the actual operation + or - */
00744         if (num_args == 1) {
00745                 e = SS::create(loc, declaration_get()->type_get().template dncast<ss_function>()->returns_get().template dncast<ss_pseudoreference>()->what_get(), psp_get(), nsp_get(),
00746                         get, r);
00747         }
00748         else {
00749                 e = SS::create(loc, declaration_get()->type_get().template dncast<ss_function>()->returns_get(), psp_get(), nsp_get(),
00750                         get, r);
00751         }
00752         /* this creates the assign operation with the sideeffect */
00753         lassert(num_args <= 3);
00754         if (l->type_get()->accept_or_ics_base_cv(v) == OR_CV_REFERENCE)
00755                 p = ss_assign::create(loc, ss_pseudoreference::instance(l->type_get().template dncast<ss_reference>()->what_get()), psp_get(), nsp_get(), l_expr, e);
00756         else
00757                 p = ss_assign::create(loc, l->type_get(), psp_get(), nsp_get(), l_expr, e);
00758                 
00759         ptr< ss_se > __se = ss_se::create(loc, p, psp_get(), nsp_get());
00760 
00761         /* psp/nsps have lists of previous/next sideeffects. this updates them */
00762         psp_get()->nse_get()->push_back(__se);
00763         nsp_get()->pse_get()->push_back(__se);
00764 
00765         if (num_args == 1) {
00766                 result_set(p);
00767         } else {
00768                 result_set(get);
00769         }
00770 }
00771 
00772 /*!
00773  * This template covers operators which have form of some op + equal
00774  *
00775  * This function takes the arguments to the operator from it's environment (the containing class'
00776  * fields) and constructs the ss_expression, the type of which is given by the template
00777  * argument.
00778  * Also, it inserts the newly created sideeffect to the sideeffect list of the guarding sequence
00779  * points.
00780  * SS - ss expression corresponding to the particular operator
00781  */
00782 template <typename SS> void or_builtin_operator_expression_creator::construct_op_equal_sideeff()
00783 {
00784         ptr< ss_se > se;
00785         ptr< ::lestes::std::source_location > loc = location_get();
00786         ptr< or_or_functional > l, r;
00787         ptr < ss_expression > e, l_expr, r_expr, l_expr_rval, r_expr_rval, r_;
00788         ptr< ss_assign > p;
00789         ::lestes::std::list< srp< or_or_functional > >::iterator it = arguments_get()->begin();
00790         ptr< or_ics_functional > l_func, r_func; 
00791         ::lestes::std::list< srp< ss_type > >::iterator it_p = declaration_get()->type_get().template dncast <ss_function>()->params_get()->begin();
00792         bool is_ptr_arith = false;
00793 
00794 
00795         l = *it;
00796         it++;
00797         r = *it;
00798 
00799         ptr< or_ics_visitor_cv > v = or_ics_visitor_cv::create();
00800         if (l->type_get()->accept_or_ics_base_cv(v) != OR_CV_PSEUDOREFERENCE) {
00801                 report << non_lval_assign << loc;
00802                 exit(1);
00803         }
00804 
00805         
00806         /* find implicit conversion between argument and function parameter types. The left has to be identity, for ss2pi to be happy (lvalue) */
00807 
00808         if (l->type_get().template dncast<ss_pseudoreference>()->what_get()->accept_or_ics_base_cv(v) == OR_CV_PTR) {
00809 
00810                 is_ptr_arith = true;
00811                 l_func = or_ics_functional_for_std_conversion::create(RANK_EXACT, l->type_get());
00812                 if(r->type_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE) {
00813                         if(r->type_get().template dncast<ss_pseudoreference>()->what_get()->accept_or_ics_base_cv(v) != OR_CV_SINT) {
00814                                 report << assign_incompatible_types << loc;
00815                                 exit(1);
00816                         }
00817                         r_func = or_find_ics(r, ss_type_sint::instance());
00818                         if (!r_func) {
00819                                 report << incompatible_types_conversion << loc;
00820                                 exit(1);
00821                         }       
00822                 }
00823                 else {
00824                         r_func = or_find_ics(r, ss_type_sint::instance());
00825                         if (!r_func) {
00826                                 report << incompatible_types_conversion << loc;
00827                                 exit(1);
00828                         }       
00829                 }
00830         } else {
00831                 l_func = or_find_ics(l, *it_p);
00832                 if (!l_func) {
00833                         report << incompatible_types_conversion << loc;
00834                         exit(1);
00835                 }       
00836                 r_func = or_find_ics(r, l->type_get().template dncast<ss_pseudoreference>()->what_get());
00837                 if (!r_func) {
00838                         report << incompatible_types_conversion << loc;
00839                         exit(1);
00840                 }       
00841 
00842         }
00843         
00844         it = arguments_get()->begin();
00845         it_p++;
00846                 
00847         /* this constructs the actual ss_expression for parameters, taking in account conversion sequences needed */
00848         l_expr = (*l_func)((*l)(psp_get(), nsp_get(), loc, sp_list_get()), psp_get(), nsp_get());
00849         r_expr = (*r_func)((*r)(psp_get(), nsp_get(), loc, sp_list_get()), psp_get(), nsp_get());
00850 
00851         /* In the case of pointer arithmetics we have to multiply the constant by the sizeof() of
00852          * the underlying type
00853          */
00854         if (is_ptr_arith) {
00855                 r_ = ss_literal::create(loc, ss_type_sint::instance(), psp_get(), nsp_get(), 
00856                                 ss_integral_literal_info::create_from_number(ss_type_sint::instance(), 
00857                                         ss_type_size_evaluator::instance()->size_get(
00858                                                 l->type_get().template dncast<ss_pseudoreference>()->what_get().template dncast<ss_pointer>()->what_get())/8));
00859                 r_expr = ss_conversion::create( loc, 
00860                                 l->type_get().template dncast<ss_pseudoreference>()->what_get(),
00861                                 psp_get(),
00862                                 nsp_get(),
00863                                 ss_mul::create( loc, 
00864                                         ss_type_sint::instance(), 
00865                                         psp_get(), 
00866                                         nsp_get(), 
00867                                         r_expr,
00868                                         r_),
00869                                 ss_type_sint::instance()
00870                                 );
00871         }
00872 
00873         if(l_expr->type_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE) {
00874                 l_expr_rval = ss_get::create(loc, l->type_get().template dncast<ss_pseudoreference>()->what_get(), psp_get(), nsp_get(), l_expr); 
00875         } else {
00876                 l_expr_rval = l_expr;
00877         }               
00878 
00879         if(r_expr->type_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE) {
00880                 r_expr_rval = ss_get::create(loc, r->type_get().template dncast<ss_pseudoreference>()->what_get(), psp_get(), nsp_get(), r_expr); 
00881         } else {
00882                 r_expr_rval = r_expr;
00883         }
00884         
00885         e = SS::create( loc, 
00886                         r_expr_rval->type_get(), 
00887                         psp_get(), 
00888                         nsp_get(), 
00889                         l_expr_rval, 
00890                         r_expr_rval);
00891 
00892         p = ss_assign::create(loc, l->type_get(), psp_get(), nsp_get(), l_expr, e);
00893         se = ss_se::create(loc, p, psp_get(), nsp_get());
00894 
00895         /* psp/nsps have lists of previous/next sideeffects. this updates them */
00896         psp_get()->nse_get()->push_back(se);
00897         nsp_get()->pse_get()->push_back(se);
00898 
00899         result_set(p);
00900 }
00901 
00902 /*!
00903  * This handles the '=' operator.
00904  */
00905 void or_builtin_operator_expression_creator::visit_ss_operator_assign( ptr< ss_operator_assign > )
00906 {
00907         ptr< ss_se > se;
00908         ptr< ::lestes::std::source_location > loc = location_get();
00909         ptr< or_or_functional > l, r, e;
00910         ptr< ss_expression > l_expr, r_expr;
00911         ptr< ss_assign > p;
00912         ::lestes::std::list< srp< or_or_functional > >::iterator it = arguments_get()->begin();
00913         ptr< or_ics_functional > l_func, r_func; 
00914         ::lestes::std::list< srp< ss_type > >::iterator it_p = declaration_get()->type_get().dncast <ss_function>()->params_get()->begin();
00915 
00916         l = *it;
00917         it++;
00918         r = *it;
00919 
00920         /* find implicit conversion between argument and function parameter types */
00921         it = arguments_get()->begin();
00922 
00923         ptr< or_ics_visitor_cv > v = or_ics_visitor_cv::create();
00924         if (l->type_get()->accept_or_ics_base_cv(v) != OR_CV_PSEUDOREFERENCE && l->type_get()->accept_or_ics_base_cv(v) != OR_CV_REFERENCE) {
00925                 report << non_lval_assign << loc;
00926                 exit(1);
00927         }
00928 
00929         /* left param should stay the same */
00930         l_func = or_ics_functional_for_std_conversion::create(RANK_EXACT, l->type_get());
00931         //l_func = or_find_ics(l, *it_p);
00932         it_p++;
00933 
00934         /* If the right parameter is not pointer, we must convert it to the type of the whole 
00935          * assignment, as ss2pi is expecting all the types in operations the same
00936          */
00937         if(l->type_get()->accept_or_ics_base_cv(v) == OR_CV_PTR) {
00938                 r_func = or_find_ics(r, *it_p);
00939                 if (!r_func) {
00940                         report << incompatible_types_conversion << loc;
00941                         exit(1);
00942                 }
00943         }
00944         else {
00945                 ptr< or_ics_visitor_cv > v1 = or_ics_visitor_cv::create();
00946                 if(declaration_get()->type_get().dncast <ss_function>()->returns_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE) {
00947                         r_func = or_find_ics(r, declaration_get()->type_get().dncast <ss_function>()->returns_get().dncast<ss_pseudoreference>()->what_get());
00948                         if (!r_func) {
00949                                 report << incompatible_types_conversion << loc;
00950                                 exit(1);
00951                         }       
00952                 }
00953                 else if(declaration_get()->type_get().dncast <ss_function>()->returns_get()->accept_or_ics_base_cv(v) == OR_CV_REFERENCE) {
00954                         r_func = or_find_ics(r, declaration_get()->type_get().dncast <ss_function>()->returns_get().dncast<ss_reference>()->what_get());
00955                         if (!r_func) {
00956                                 report << incompatible_types_conversion << loc;
00957                                 exit(1);
00958                         }       
00959                 }
00960                 else 
00961                 {
00962                         r_func = or_find_ics(r, declaration_get()->type_get().dncast <ss_function>()->returns_get());
00963                         if (!r_func) {
00964                                 report << incompatible_types_conversion << loc;
00965                                 exit(1);
00966                         }       
00967                 }
00968         }
00969                 
00970         /* this constructs the actual ss_expression for parameters, taking in account conversion sequences needed */
00971         l_expr = (*l_func)((*l)(psp_get(), nsp_get(), loc, sp_list_get()), psp_get(), nsp_get());
00972         r_expr = (*r_func)((*r)(psp_get(), nsp_get(), loc, sp_list_get()), psp_get(), nsp_get());
00973         
00974         p = ss_assign::create(  loc,
00975                                 //l->type_get(),
00976                                 declaration_get()->type_get().dncast <ss_function>()->returns_get(),
00977                                 psp_get(),
00978                                 nsp_get(),
00979                                 l_expr,
00980                         r_expr);
00981         se = ss_se::create(loc, p, psp_get(), nsp_get());
00982 
00983         /* psp/nsps have lists of previous/next sideeffects. this updates them */
00984         psp_get()->nse_get()->push_back(se);
00985         nsp_get()->pse_get()->push_back(se);
00986 
00987         result_set(p);
00988 }
00989 
00990 
00991 /*!
00992  * comma is handled separately in it's own functional.
00993  */
00994 void or_builtin_operator_expression_creator::visit_ss_operator_comma( ptr< ss_operator_comma > )
00995 {
00996         /* nop */
00997 }
00998 
00999 void or_builtin_operator_expression_creator::visit_ss_dummy_name( ptr< ss_dummy_name> )
01000 {
01001         lassert2(false, "Dummy name unhandled in or_builtin_operator_expression_creator\n");
01002 }
01003 
01004 void or_builtin_operator_expression_creator::visit_ss_operator_function_call( ptr< ss_operator_function_call >)
01005 {
01006         lassert2(false, "There is no such builtin op\n");
01007 }
01008 
01009 void or_builtin_operator_expression_creator::visit_ss_operator_array( ptr< ss_operator_array >)
01010 {
01011         lassert2(false, "ss_operator_array not yet implemented in or_builtin_operator_expression_creator\n");
01012 }
01013 
01014 void or_builtin_operator_expression_creator::visit_ss_operator_access( ptr< ss_operator_access >)
01015 {
01016         lassert2(false, "ss_operator_access not yet implemented in or_builtin_operator_expression_creator\n");
01017 }
01018 void or_builtin_operator_expression_creator::visit_ss_operator_access_member( ptr< ss_operator_access_member >)
01019 {
01020         lassert2(false, "ss_operator_access_member not yet implemented in or_builtin_operator_expression_creator\n");
01021 }
01022 
01023 void or_builtin_operator_expression_creator::visit_ss_operator_ternary( ptr< ss_operator_ternary >)
01024 {
01025         lassert2(false, "ss_operator_ternary not yet implemented in or_builtin_operator_expression_creator\n");
01026 }
01027 
01028 void or_builtin_operator_expression_creator::visit_ss_ordinary_name( ptr< ss_ordinary_name >)
01029 {
01030         lassert2(false,"This type of name is not a builtin operator name");
01031 }
01032 
01033 void or_builtin_operator_expression_creator::visit_ss_conversion_name( ptr< ss_conversion_name >)
01034 {
01035         lassert2(false,"This type of name is not a builtin operator name");
01036 }
01037 
01038 
01039 /* == It has not been decided yet how to handle the following == */
01040 void or_builtin_operator_expression_creator::visit_ss_operator_new( ptr< ss_operator_new >)
01041 {
01042 }
01043 
01044 void or_builtin_operator_expression_creator::visit_ss_operator_delete( ptr< ss_operator_delete >)
01045 {
01046 }
01047 
01048 void or_builtin_operator_expression_creator::visit_ss_operator_new_array( ptr< ss_operator_new_array >)
01049 {
01050 }
01051 
01052 void or_builtin_operator_expression_creator::visit_ss_operator_delete_array( ptr< ss_operator_delete_array >)
01053 {
01054 }
01055 /* == End of not yet decided == */
01056 
01057 /* == The following binary operators without sideeffect are just straightforward uses of the template written above == */
01058 void or_builtin_operator_expression_creator::visit_ss_operator_land( ptr< ss_operator_land >)
01059 {
01060         construct_bin_op_nosideeff_newsp<ss_land>();
01061 }
01062 
01063 void or_builtin_operator_expression_creator::visit_ss_operator_lor( ptr< ss_operator_lor >)
01064 {
01065         construct_bin_op_nosideeff_newsp<ss_lor>();
01066 }
01067 
01068 void or_builtin_operator_expression_creator::visit_ss_operator_add( ptr< ss_operator_add >)
01069 {
01070         ::lestes::std::list< srp< or_or_functional > >::size_type num_args = arguments_get()->size();
01071         ptr< or_or_functional_literal > literal_zero;
01072         if(num_args == 1) {
01073                 literal_zero = or_or_functional_literal::create(ss_type_sint::instance(),ss_integral_literal_info::create_from_number(ss_type_sint::instance(), 0));
01074                 arguments_get()->push_front(literal_zero);
01075         }
01076         construct_bin_op_nosideeff_arith<ss_add>();
01077 }
01078 
01079 void or_builtin_operator_expression_creator::visit_ss_operator_sub( ptr< ss_operator_sub >)
01080 {
01081         ::lestes::std::list< srp< or_or_functional > >::size_type num_args = arguments_get()->size();
01082         ptr< or_or_functional_literal > literal_zero;
01083         if(num_args == 1) {
01084                 literal_zero = or_or_functional_literal::create(ss_type_sint::instance(),ss_integral_literal_info::create_from_number(ss_type_sint::instance(), 0));
01085                 arguments_get()->push_front(literal_zero);
01086         }
01087         construct_bin_op_nosideeff_arith<ss_sub>();
01088 }
01089 
01090 void or_builtin_operator_expression_creator::visit_ss_operator_mul( ptr< ss_operator_mul >)
01091 {
01092         ::lestes::std::list< srp< or_or_functional > >::size_type num_args = arguments_get()->size();
01093         if (num_args == 2)
01094                 construct_bin_op_nosideeff_arith<ss_mul>();
01095         else if (num_args == 1) 
01096                 construct_un_op_nosideeff<ss_dereference>();
01097         else
01098                 lassert2(false, "Strange, >2 arguments to operator*\n");
01099 }
01100 
01101 void or_builtin_operator_expression_creator::visit_ss_operator_div( ptr< ss_operator_div >)
01102 {
01103         construct_bin_op_nosideeff_arith<ss_div>();
01104 }
01105 
01106 void or_builtin_operator_expression_creator::visit_ss_operator_mod( ptr< ss_operator_mod >)
01107 {
01108         construct_bin_op_nosideeff_arith<ss_mod>();
01109 }
01110 
01111 void or_builtin_operator_expression_creator::visit_ss_operator_bxor( ptr< ss_operator_bxor >)
01112 {
01113         construct_bin_op_nosideeff_arith<ss_bxor>();
01114 }
01115 
01116 void or_builtin_operator_expression_creator::visit_ss_operator_band( ptr< ss_operator_band >)
01117 {
01118         ::lestes::std::list< srp< or_or_functional > >::size_type num_args = arguments_get()->size();
01119 
01120         if (num_args == 1)
01121                 construct_un_op_nosideeff<ss_address_of>();
01122         else
01123                 construct_bin_op_nosideeff_arith<ss_band>();
01124 }
01125 
01126 void or_builtin_operator_expression_creator::visit_ss_operator_bor( ptr< ss_operator_bor >)
01127 {
01128         construct_bin_op_nosideeff_arith<ss_bor>();
01129 }
01130 void or_builtin_operator_expression_creator::visit_ss_operator_shr( ptr< ss_operator_shr >)
01131 {
01132         construct_bin_op_nosideeff_arith<ss_shr>();
01133 }
01134 
01135 void or_builtin_operator_expression_creator::visit_ss_operator_shl( ptr< ss_operator_shl >)
01136 {
01137         construct_bin_op_nosideeff_arith<ss_shl>();
01138 }
01139 
01140 void or_builtin_operator_expression_creator::visit_ss_operator_sbl( ptr< ss_operator_sbl >)
01141 {
01142         construct_bin_op_nosideeff<ss_sbl>();
01143 }
01144 
01145 void or_builtin_operator_expression_creator::visit_ss_operator_sbg( ptr< ss_operator_sbg >)
01146 {
01147         construct_bin_op_nosideeff<ss_sbg>();
01148 }
01149 
01150 void or_builtin_operator_expression_creator::visit_ss_operator_sbng( ptr< ss_operator_sbng >)
01151 {
01152         construct_bin_op_nosideeff<ss_sbng>();
01153 }
01154 
01155 void or_builtin_operator_expression_creator::visit_ss_operator_sbnl( ptr< ss_operator_sbnl >)
01156 {
01157         construct_bin_op_nosideeff<ss_sbnl>();
01158 }
01159 
01160 void or_builtin_operator_expression_creator::visit_ss_operator_sbe( ptr< ss_operator_sbe >)
01161 {
01162         construct_bin_op_nosideeff<ss_sbe>();
01163 }
01164 
01165 void or_builtin_operator_expression_creator::visit_ss_operator_sbne( ptr< ss_operator_sbne >)
01166 {
01167         construct_bin_op_nosideeff<ss_sbne>();
01168 }
01169 /* == End of binary without sideeffect == */
01170 
01171 /* == The following unary opetrators without sideffect are just straightfoward uses of the template above == */
01172 void or_builtin_operator_expression_creator::visit_ss_operator_bnot( ptr< ss_operator_bnot >)
01173 {
01174         construct_un_op_nosideeff<ss_bnot>();
01175 }
01176 
01177 void or_builtin_operator_expression_creator::visit_ss_operator_lnot( ptr< ss_operator_lnot >)
01178 {
01179         construct_un_op_nosideeff<ss_lnot>();
01180 }
01181 
01182 /* == The end of unary operators without sideeffect == */
01183 
01184 /* == The following compound binary opetrators with assignment sideffect are just straightfoward uses of the template written above == */
01185 void or_builtin_operator_expression_creator::visit_ss_operator_assign_add( ptr< ss_operator_assign_add >)
01186 {
01187         construct_op_equal_sideeff<ss_add>();
01188 }
01189 
01190 void or_builtin_operator_expression_creator::visit_ss_operator_assign_sub( ptr< ss_operator_assign_sub >)
01191 {
01192         construct_op_equal_sideeff<ss_sub>();
01193 }
01194 
01195 void or_builtin_operator_expression_creator::visit_ss_operator_assign_mul( ptr< ss_operator_assign_mul >)
01196 {
01197         construct_op_equal_sideeff<ss_mul>();
01198 }
01199 
01200 void or_builtin_operator_expression_creator::visit_ss_operator_assign_div( ptr< ss_operator_assign_div >)
01201 {
01202         construct_op_equal_sideeff<ss_mul>();
01203 }
01204 
01205 void or_builtin_operator_expression_creator::visit_ss_operator_assign_mod( ptr< ss_operator_assign_mod >)
01206 {
01207         construct_op_equal_sideeff<ss_mod>();
01208 }
01209 
01210 void or_builtin_operator_expression_creator::visit_ss_operator_assign_bxor( ptr< ss_operator_assign_bxor >)
01211 {
01212         construct_op_equal_sideeff<ss_bxor>();
01213 }
01214 
01215 void or_builtin_operator_expression_creator::visit_ss_operator_assign_band( ptr< ss_operator_assign_band >)
01216 {
01217         construct_op_equal_sideeff<ss_band>();
01218 }
01219 
01220 void or_builtin_operator_expression_creator::visit_ss_operator_assign_bor( ptr< ss_operator_assign_bor >)
01221 {
01222         construct_op_equal_sideeff<ss_bor>();
01223 }
01224 
01225 void or_builtin_operator_expression_creator::visit_ss_operator_assign_shl( ptr< ss_operator_assign_shl >)
01226 {
01227         construct_op_equal_sideeff<ss_shl>();
01228 }
01229 
01230 void or_builtin_operator_expression_creator::visit_ss_operator_assign_shr( ptr< ss_operator_assign_shr >)
01231 {
01232         construct_op_equal_sideeff<ss_shr>();
01233 }
01234 
01235 /* == End of compound binary == */
01236 
01237 
01238 /* When calling overload resolution for one of prefix/postfix, extra expression representing
01239  * zero of type int will be created
01240  *
01241  * It is necessary to distinguish between prefix and postfix. This is done in the templated 
01242  * function.
01243  */
01244 void or_builtin_operator_expression_creator::visit_ss_operator_inc( ptr< ss_operator_inc >)
01245 {
01246         construct_op_crement<ss_add>();
01247 }
01248 
01249 void or_builtin_operator_expression_creator::visit_ss_operator_dec( ptr< ss_operator_dec >)
01250 {
01251         construct_op_crement<ss_sub>();
01252 }
01253 
01254 /* == END OF BUILTIN OPERATOR EXPRESSION CREATOR == */
01255 
01256 /* The following cases are not possible, because we know that we have the pointer
01257  * to builtin or function declaration
01258  */
01259 
01260 void or_declaration_helper::visit_ss_injected_class_declaration( ptr< ss_injected_class_declaration >)
01261 {
01262         lassert(false);
01263 }
01264 
01265 void or_declaration_helper::visit_ss_structure_declaration( ptr< ss_structure_declaration >)
01266 {
01267         lassert(false);
01268 }
01269 
01270 void or_declaration_helper::visit_ss_namespace_definition( ptr< ss_namespace_definition >)
01271 {
01272         lassert(false);
01273 }
01274 
01275 void or_declaration_helper::visit_ss_object_declaration( ptr< ss_object_declaration >)
01276 {
01277         lassert(false);
01278 }
01279 
01280 void or_declaration_helper::visit_ss_bitfield_declaration( ptr< ss_bitfield_declaration >)
01281 {
01282         lassert(false);
01283 }
01284 
01285 void or_declaration_helper::visit_ss_parameter_declaration( ptr< ss_parameter_declaration >)
01286 {
01287         lassert(false);
01288 }
01289 
01290 void or_declaration_helper::visit_ss_enumerator_declaration( ptr< ss_enumerator_declaration >)
01291 {
01292         lassert(false);
01293 }
01294 
01295 void or_declaration_helper::visit_ss_enum_definition( ptr< ss_enum_definition >)
01296 {
01297         lassert(false);
01298 }
01299 
01300 void or_declaration_helper::visit_ss_typedef_definition( ptr< ss_typedef_definition >)
01301 {
01302         lassert(false);
01303 }
01304 
01305 void or_declaration_helper::visit_ss_using_declaration( ptr< ss_using_declaration >)
01306 {
01307         lassert(false);
01308 }
01309 
01310 void or_declaration_helper::visit_ss_compound_stmt_declaration( ptr< ss_compound_stmt_declaration >)
01311 {
01312         lassert(false);
01313 }
01314 void or_declaration_helper::visit_ss_fake_declaration( ptr< ss_fake_declaration >)
01315 {
01316         lassert(false);
01317 }
01318 
01319 /*!
01320  * In case of function declaration creation of proper funcall is needed (done by or_funcall_creator)
01321  * and returning the created funcall via result
01322  */
01323 void or_declaration_helper::visit_ss_function_declaration( ptr< ss_function_declaration > a )
01324 {
01325         ptr< or_funcall_creator > crtr = or_funcall_creator::create(a, psp_get(), nsp_get(), arguments_get(), location_get(), sp_list_get() );
01326         ptr< ss_declaration > decl = a->contained_in_get()->declared_by_get();
01327 
01328         decl->accept_ss_declaration_visitor(crtr);
01329         result_set(crtr->result_get());
01330 }
01331 
01332 /*!
01333  * In case of function declaration creation of proper funcall is needed (done by or_funcall_creator)
01334  * and returning the created funcall via result
01335  *
01336  * \todo adapt to member function call. FIXME TODO
01337  */
01338 void or_declaration_helper::visit_ss_method_declaration( ptr< ss_method_declaration > a )
01339 {
01340         ptr< or_funcall_creator > crtr = or_funcall_creator::create(a, psp_get(), nsp_get(), arguments_get(), location_get(), sp_list_get() );
01341         ptr< ss_declaration > decl = a->contained_in_get()->declared_by_get();
01342 
01343         decl->accept_ss_declaration_visitor(crtr);
01344         result_set(crtr->result_get());
01345 }
01346 /*!
01347  * In case of builtin operator we delegate the creation of appropriate structures to
01348  * the visitor over the operator name, ie. we delegate the decission to somebody who
01349  * makes it according to the kind of the operator
01350  */
01351 void or_declaration_helper::visit_ss_builtin_operator_declaration( ptr< ss_builtin_operator_declaration > a )
01352 {
01353         ptr< or_builtin_operator_expression_creator > decl_v = or_builtin_operator_expression_creator::create(a, psp_get(), nsp_get(), arguments_get(),
01354                         location_get(), sp_list_get());
01355         a->name_get()->accept_ss_decl_name_visitor(decl_v);
01356         result_set(decl_v->result_get());
01357 }
01358 
01359 
01360 void or_funcall_creator::visit_ss_enumerator_declaration( ptr< ss_enumerator_declaration >)
01361 {
01362         lassert(false);
01363 }
01364 void or_funcall_creator::visit_ss_using_declaration( ptr< ss_using_declaration >)
01365 {
01366         lassert(false);
01367 }
01368 void or_funcall_creator::visit_ss_compound_stmt_declaration( ptr< ss_compound_stmt_declaration >)
01369 {
01370         lassert(false);
01371 }
01372 void or_funcall_creator::visit_ss_fake_declaration( ptr< ss_fake_declaration >)
01373 {
01374         lassert(false);
01375 }
01376 /*!
01377  * if the parent scope is namespace, we have to create function call
01378  */
01379 void or_funcall_creator::visit_ss_namespace_definition( ptr< ss_namespace_definition >)
01380 {
01381         /* first, we create prefunc and postfunc sequence points. The sequence points are
01382          * ordered as following: 
01383          *
01384          * psp <-> ARGUMENTS <-> prefunc_sp <-> FUNCTION CALL <-> postfunc_sp <-> nsp 
01385          */
01386         lint level = MAX(psp_get()->level_get(), nsp_get()->level_get())+1;
01387         ptr< ss_sp > prefunc_sp = ss_sp::create(location_get(), psp_get(), NULL, level);
01388         sp_list_get()->push_back(prefunc_sp);
01389         ptr< ss_sp > postfunc_sp = ss_sp::create(location_get(), prefunc_sp, nsp_get(), level);
01390         sp_list_get()->push_back(postfunc_sp);
01391         prefunc_sp->nsp_set(postfunc_sp);
01392         ptr< ss_funcall > f;
01393         
01394         /* now process the functionals representing the parameters and create ss_expression for every
01395          * parameter, with proper sequence points ordering 
01396          */
01397 
01398         ::lestes::std::list< srp< or_or_functional > > ::iterator it = arguments_get()->begin();
01399         ::lestes::std::list< srp< ss_declaration > >::iterator it_p = declaration_get().dncast<ss_function_declaration>()->parameters_get()->contents_get()->begin();
01400         ptr< ::lestes::std::list< srp< ss_expression > > > arg_exprs = ::lestes::std::list< srp< ss_expression > >::create();
01401 
01402         /* create list of arguments (or_or_functional::operator() creates the ss_expression) */ 
01403         for (; it != arguments_get()->end() ; it++, it_p++) {
01404                 ptr< or_ics_functional > p_func = or_find_ics((*it), (*it_p)->type_get());
01405                 if (!p_func) {
01406                         report << incompatible_types_conversion << location_get();
01407                         exit(1);
01408                 }       
01409 
01410                 arg_exprs->push_back((*p_func)(((**it)(psp, prefunc_sp, location_get(), sp_list_get() )), psp, prefunc_sp));
01411         }
01412 
01413         ptr< or_ics_visitor_cv > v = or_ics_visitor_cv::create();
01414         if(declaration_get()->type_get().dncast<ss_function>()->returns_get()->accept_or_ics_base_cv(v) == OR_CV_REFERENCE || 
01415                         declaration_get()->type_get().dncast<ss_function>()->returns_get()->accept_or_ics_base_cv(v) == OR_CV_VOID)
01416 
01417                 result_set(f = ss_funcall::create(      location_get(), 
01418                                                 declaration_get()->type_get().dncast<ss_function>()->returns_get(), 
01419                                                 prefunc_sp, 
01420                                                 postfunc_sp, 
01421                                                 arg_exprs, 
01422                                                 declaration_get()));
01423                                                 
01424         else
01425                 result_set(ss_get::create(location_get(), 
01426                                         declaration_get()->type_get().dncast<ss_function>()->returns_get(),  
01427                                         postfunc_sp,
01428                                         nsp_get(),
01429                                         f = ss_funcall::create( location_get(), 
01430                                                                 ss_pseudoreference::instance(declaration_get()->type_get().dncast<ss_function>()->returns_get()), 
01431                                                                 prefunc_sp, 
01432                                                                 postfunc_sp, 
01433                                                                 arg_exprs, 
01434                                                                 declaration_get()))
01435                                         );
01436         /* Funcall introduces new sideeffect */
01437 
01438         ptr< ss_se > se = ss_se::create(location_get(), f, prefunc_sp, postfunc_sp);
01439         /* psp/nsps have lists of previous/next sideeffects. this updates them */
01440         prefunc_sp->nse_get()->push_back(se);
01441         postfunc_sp->pse_get()->push_back(se);
01442                 
01443 }
01444 
01445 void or_funcall_creator::visit_ss_structure_declaration( ptr< ss_structure_declaration >)
01446 {
01447         // TODO construct mfuncall, vfuncall (declaration and object parameter are passed to the visitor
01448         // context_get(), declaration_get(), object_expression_get()
01449 
01450         lassert2(false, "mfuncall/vfuncall not yet implemented in or_funcall_creator\n");
01451 }
01452 void or_funcall_creator::visit_ss_object_declaration( ptr< ss_object_declaration >)
01453 {
01454         lassert2(false,"Object declaration shall not be parent of function declaration");
01455 }
01456 
01457 void or_funcall_creator::visit_ss_bitfield_declaration( ptr< ss_bitfield_declaration >)
01458 {
01459         lassert2(false,"Bitfield declaration shall not be parent of function declaration");
01460 }
01461 
01462 void or_funcall_creator::visit_ss_parameter_declaration( ptr< ss_parameter_declaration >)
01463 {
01464         lassert2(false,"Parameter declaration shall not be parent of function declaration");
01465 }
01466 
01467 void or_funcall_creator::visit_ss_injected_class_declaration( ptr< ss_injected_class_declaration >)
01468 {
01469         lassert2(false,"Injected class declaration shall not be parent of function declaration");
01470 }
01471 
01472 void or_funcall_creator::visit_ss_enum_definition( ptr< ss_enum_definition >)
01473 {
01474         lassert2(false,"Enum declaration shall not be parent of function declaration");
01475 }
01476 
01477 void or_funcall_creator::visit_ss_typedef_definition( ptr< ss_typedef_definition >)
01478 {
01479         lassert2(false,"Typedef declaration shall not be parent of function declaration");
01480 }
01481 
01482 void or_funcall_creator::visit_ss_function_declaration( ptr< ss_function_declaration >)
01483 {
01484         lassert2(false,"Function declaration declaration shall not be parent of function declaration");
01485 }
01486 
01487 void or_funcall_creator::visit_ss_method_declaration( ptr< ss_method_declaration >)
01488 {
01489         lassert2(false,"Method declaration shall not be parent of function declaration");
01490 }
01491 
01492 void or_funcall_creator::visit_ss_builtin_operator_declaration( ptr< ss_builtin_operator_declaration >)
01493 {
01494         lassert2(false,"Builtin op declaration shall not be parent of function declaration");
01495 }
01496 
01497 
01498 /*!
01499  * This is overloaded operator () of functional used by overload resolution.
01500  * It creates corresponding funcall and returns it's expression.
01501  *
01502  * \bug context doesn't contain VMT yet, so vfuncall is irrelevant
01503  *
01504  * \return pointer to expression, representing the function call
01505  */
01506 ptr< ss_expression > or_or_functional_concrete::operator()(ptr< ss_sp > psp, ptr< ss_sp > nsp, ptr< ::lestes::std::source_location > location, ptr< ::lestes::std::list< srp< ss_sp > > > sp_list)
01507 {
01508         ptr< or_declaration_helper > v = or_declaration_helper::create(declaration_get(), psp, nsp, args_get(), location, sp_list);
01509         declaration_get()->accept_ss_declaration_visitor(v);
01510         return v->result_get();
01511 }
01512 
01513 /*!
01514  * This is overloaded operator () of functional used by overload resolution.
01515  * It creates corresponding funcall and returns it's expression.
01516  *
01517  * This functional handles the special case of comma operator. This is handled 
01518  * in a slightly different way (as some other operators, line unary & and ->), as
01519  * they exist for infinite number of types and their declarations are not filled in
01520  * the builtin op decl_seq
01521  *
01522  * \bug context doesn't contain VMT yet, so vfuncall is irrelevant
01523  *
01524  * \return pointer to expression, representing the function call
01525  */
01526 ptr< ss_expression > or_or_functional_comma::operator()(ptr< ss_sp > psp, ptr< ss_sp > nsp, ptr< ::lestes::std::source_location > location, ptr< ::lestes::std::list< srp< ss_sp > > > sp_list)
01527 {
01528         ptr< or_or_functional > l, r;
01529         ptr< ss_expression > l_expr, r_expr;
01530         ptr< or_ics_functional > l_func, r_func;
01531         ptr< ::lestes::std::source_location > loc = location;
01532         ::lestes::std::list< srp< or_or_functional > >::iterator it = args_get()->begin();
01533 
01534         l = *it;
01535         it++;
01536         r = *it++;
01537 
01538         /* find implicit conversion between argument and function parameter types. Nop here. */
01539 
01540         /* create new sequence point and add to lists properly */
01541         lint level = MAX(psp->level_get(), nsp->level_get())+1;
01542         ptr< ss_sp > new_sp = ss_sp::create(loc, psp, nsp, level);
01543         sp_list->push_back(new_sp);
01544 
01545         /* this constructs the actual ss_expression for parameters, taking in account conversion sequences needed */
01546         l_expr = (*l)(psp, new_sp, loc, sp_list);
01547         r_expr = (*r)(new_sp, nsp, loc, sp_list);
01548 
01549         /* get the time of this expression */
01550         return r_expr;
01551 }
01552 
01553 ptr< ss_expression > or_or_functional_addrof::operator()(ptr< ss_sp > psp, ptr< ss_sp > nsp, ptr< ::lestes::std::source_location > location, ptr< ::lestes::std::list< srp< ss_sp > > > sp_list)
01554 {
01555         ptr< or_or_functional > l;
01556         ptr< ss_expression > l_expr;
01557         ptr< or_ics_functional > l_func;
01558         ptr< ::lestes::std::source_location > loc = location;
01559         ::lestes::std::list< srp< or_or_functional > >::iterator it = args_get()->begin();
01560 
01561         l = *it;
01562 
01563         /* find implicit conversion between argument and function parameter types. Nop here. */
01564 
01565         /* this constructs the actual ss_expression for parameters, taking in account conversion sequences needed */
01566         l_expr = (*l)(psp, nsp, loc, sp_list);
01567 
01568         /* get the time of this expression */
01569         return ss_address_of::create(location, type_get(), psp, nsp, l_expr);
01570 }
01571 
01572 /*!
01573  * This is overloaded operator () of functional used by overload resolution.
01574  * It servers for purpose of creating ss_this_expr expression.
01575  * It creates corresponding ss_this_expr expression.
01576  *
01577  * \return pointer to expression, representing the function call
01578  */
01579 ptr< ss_expression > or_or_functional_this::operator()(ptr< ss_sp > psp, ptr< ss_sp > nsp, ptr< ::lestes::std::source_location > location, ptr< ::lestes::std::list< srp< ss_sp > > >)
01580 {
01581         return ss_this_expr::create(location,
01582                         sa_statements::instance()->current_function_get()->type_get().dncast<ss_member_function>()->this_type_get(), psp, nsp);
01583 }
01584 
01585 /*!
01586  * This is overloaded operator () of functional used by overload resolution.
01587  * It servers for purpose of creating ss_literal expression from ss_literal_info
01588  * It creates corresponding ss_literal expression.
01589  *
01590  * \return pointer to expression, representing the function call
01591  */
01592 ptr< ss_expression > or_or_functional_literal::operator()(ptr< ss_sp > psp, ptr< ss_sp > nsp, ptr< ::lestes::std::source_location > location, ptr< ::lestes::std::list< srp< ss_sp > > >)
01593 {
01594         /* TODO as soon as there are other than integral literals, this or_or_functional should 
01595          * hold (in some enum) the type of the literal and fill the type field of the newly
01596          * created ss_literal accordingly
01597          */
01598         return ss_literal::create(location, type_get(), psp, nsp, literal_get());
01599 }
01600 
01601 /*!
01602  * This functional represents ambiguous conversion and list of viables
01603  * should be returned. This is not currently possible, as the prototype
01604  * restricts us to return ptr< ss_expression >
01605  *
01606  * The list of viables is needed to provide user with 'candidates are: blah blah'
01607  * message
01608  */
01609 ptr< ss_expression > or_or_functional_ambiguous::operator()(ptr< ss_sp > psp, ptr< ss_sp > nsp, ptr< ::lestes::std::source_location > location, ptr< ::lestes::std::list< srp< ss_sp > > >)
01610 {
01611         /* just to avoid unused parameter warning */
01612         psp = psp;
01613         nsp = nsp;
01614         location = location;
01615         /* TODO dump the viables to the user */
01616         report << ambiguous_result << location;
01617         exit(1);
01618 }
01619 
01620 /*!
01621  * This functional represents no-viables-found functional.
01622  */
01623 ptr< ss_expression > or_or_functional_noviable::operator()(ptr< ss_sp > psp, ptr< ss_sp > nsp, ptr< ::lestes::std::source_location > location, ptr< ::lestes::std::list< srp< ss_sp > > >)
01624 {
01625         /* just to avoid unused parameter warning */
01626         psp = psp;
01627         nsp = nsp;
01628         location = location;
01629         /* TODO dump the viables to the user */
01630         report << no_viable_found << location;
01631         exit(1);
01632 }
01633 
01634 /*!
01635  * This functional represents the list of function declarations, from which the 
01636  * right one should be chosen. The function declarations are obtained from the
01637  * functional directly using _get() getter, not by calling the operator(), so
01638  * this would lassert
01639  */
01640 ptr< ss_expression > or_or_functional_func_decl_set::operator()(ptr< ss_sp > psp, ptr< ss_sp > nsp, ptr< ::lestes::std::source_location > location, ptr< ::lestes::std::list< srp< ss_sp > > > sp_list)
01641 {
01642         /* just to avoid unused param warning :) */
01643         psp = psp;
01644         nsp = nsp;
01645         location = location;
01646         sp_list = sp_list;
01647 
01648         lassert2(false, "operator() on or_or_functional_func_decl_set shouldn't be called");
01649 }
01650 
01651 /*!
01652  * This functional holds a single declaration of variable, so it creates varref 
01653  * for the variable in question.
01654  *
01655  * There are special cases to be handled here - for example constructing varref 
01656  * if the declaration in question is name of a type doesn't make sense - we have
01657  * to handle function-style-cast somehow instead. This is TODO
01658  *
01659  * If the obtained declaration is namespace declaration, boom.
01660  */
01661 ptr< ss_expression > or_or_functional_decl::operator()(ptr< ss_sp > psp, ptr< ss_sp > nsp, ptr< ::lestes::std::source_location > location, ptr< ::lestes::std::list< srp< ss_sp > > > sp_list)
01662 {
01663         /* avoid gcc unused var warning */
01664         sp_list = sp_list;
01665         
01666         ptr< ss_decl_to_enum > v = ss_decl_to_enum::create();
01667         ss_decl_enum e;
01668 
01669         declaration_get()->accept_ss_declaration_visitor(v);
01670         e = v->result_get();
01671 
01672         if (e == NAMESPACE_DEFINITION || e == USING_DECLARATION) {
01673                 lassert2(false, "The declaration in or_or_functional_decl::operator() is wrong (namespace || using)");
01674         } 
01675         else if (e == TYPEDEF_DEFINITION) {
01676                 lassert2(false, "Function style cast is not yet implemented && varref for typename is wrong");
01677         }
01678         
01679         /* return the apropriate varref */
01680         else { 
01681                 /* if the type is not (pseudo)reference, create pseudoreference. otherwise just var_ref */
01682                 ptr< or_ics_visitor_cv > v = or_ics_visitor_cv::create();
01683                 if(declaration_get()->type_get()->accept_or_ics_base_cv(v) == OR_CV_REFERENCE || declaration_get()->type_get()->accept_or_ics_base_cv(v) == OR_CV_PSEUDOREFERENCE ) 
01684                         return ss_var_ref::create(location, declaration_get()->type_get(), psp, nsp, declaration_get());
01685                 else
01686                         return ss_var_ref::create(location, ss_pseudoreference::instance(declaration_get()->type_get()), psp, nsp, declaration_get());
01687         }
01688 }
01689 
01690 
01691 end_package(sem);
01692 end_package(cplus);
01693 end_package(lang);
01694 end_package(lestes);
01695 

Generated on Mon Feb 12 18:22:44 2007 for lestes by doxygen 1.5.1-20070107