ss_type.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   \brief Semantic structures definition.
00030   
00031   Definition of methods of semantic structures (ss_type classes).
00032 */
00033 #include <lestes/lang/cplus/sem/ss_type.hh>
00034 #include <lestes/lang/cplus/sem/ss_misc.g.hh>
00035 #include <lestes/lang/cplus/sem/ss_type.g.hh>
00036 #include <lestes/lang/cplus/sem/ss_type_builtin.g.hh>
00037 #include <lestes/lang/cplus/sem/ss_type2info.g.hh>
00038 #include <lestes/std/lassert.hh>
00039 
00040 package(lestes);
00041 package(lang);
00042 package(cplus);
00043 package(sem);
00044 
00045 /*!
00046   Returns void flag for the general type.
00047   \return The void flag, that is, false.
00048 */
00049 bool ss_type::is_void()
00050 {
00051         return false;
00052 }
00053 
00054 
00055 /*!
00056   Returns void flag for this type.
00057   \return The void flag, that is, true.
00058 */
00059 bool ss_void::is_void()
00060 {
00061         return true;
00062 }
00063 
00064 /*!
00065   Returns void flag for this type.
00066   \return The void flag of the underlying type.
00067 */
00068 bool ss_volatile::is_void()
00069 {
00070         return what->is_void();
00071 }
00072 
00073 /*!
00074   Returns void flag for this type.
00075   \return The void flag of the underlying type.
00076 */
00077 bool ss_const::is_void()
00078 {
00079         return what->is_void();
00080 }
00081 
00082 /*!
00083   Returns void flag for this type.
00084   \return The void flag of the underlying type.
00085 */
00086 bool ss_const_volatile::is_void()
00087 {
00088         return what->is_void();
00089 }
00090 
00091 /*!
00092   Returns volatile flag for general type.
00093   \return The volatile flag, that is, false.
00094 */
00095 bool ss_type::is_volatile()
00096 {
00097         return false;
00098 }
00099 
00100 /*!
00101   Returns volatile flag for this type.
00102   \return The volatile flag, that is, true.
00103 */
00104 bool ss_volatile::is_volatile()
00105 {
00106         return true;
00107 }
00108 
00109 /*!
00110   Returns volatile flag for this type.
00111   \return The volatile flag, that is, true.
00112 */
00113 bool ss_const_volatile::is_volatile()
00114 {
00115         return true;
00116 }
00117 
00118 /*!
00119   Returns volatile flag for this type.
00120   \return The volatile flag, which depends on referenced type.
00121 */
00122 bool ss_referential::is_volatile()
00123 {
00124         return what->is_volatile();
00125 }
00126 
00127 /*!
00128   Returns void flag for this type.
00129   \return The void flag, which depends on referenced type.
00130 */
00131 bool ss_referential::is_void()
00132 {
00133         return what->is_void();
00134 }
00135 
00136 /*!
00137   Returns constized version of a given type.
00138   The constization is an idempotent operation.
00139   Constization and volatilization is commutative.
00140   \pre x != NULL
00141   \param x  The type to make const.
00142   \return  The constized type.
00143 */
00144 ptr <ss_type> ss_const::instance(ptr<ss_type> x)
00145 {
00146         the_instances->dump_barrier_set(true); // XXX: needed just once :-I
00147 
00148         lassert(x);
00149         srp<ss_type> &result = (*the_instances)[x];
00150 
00151         if (result)
00152                 return result;
00153 
00154         ptr<ss_type2info> ssti = ss_type2info::create();
00155 
00156         switch (ssti->process(x)) {
00157                 case ss_type2info::SS_CONST:
00158                 case ss_type2info::SS_CONST_VOLATILE:
00159                         return result = x;
00160                 case ss_type2info::SS_VOLATILE:
00161                         // this is the only place to create const_volatile
00162                         return result = ss_const_volatile::create(ssti->ss_volatile_object_get()->what_get());
00163                 default:
00164                         break;
00165         }
00166         
00167         return result = ss_const::create(x);
00168 }
00169 
00170 /*!
00171   Returns volatilized version of a given type.
00172   The volatilization is an idempotent operation.
00173   Constization and volatilization is commutative.
00174   \pre x != NULL
00175   \param x  The type to make volatile.
00176   \return  The volatilized type.
00177 */
00178 ptr<ss_type> ss_volatile::instance(ptr<ss_type> x)
00179 {
00180         the_instances->dump_barrier_set(true); // XXX: needed just once :-I
00181 
00182         lassert(x);
00183         srp <ss_type> &result = (*the_instances)[x];
00184 
00185         if (result) 
00186                 return result;
00187 
00188         ptr<ss_type2info> ssti = ss_type2info::create();
00189 
00190         switch (ssti->process(x)) {
00191         case ss_type2info::SS_VOLATILE:
00192         case ss_type2info::SS_CONST_VOLATILE:
00193                 return result = x;
00194         case ss_type2info::SS_CONST:
00195                 // create ss_const_volatile only via instance of ss_const
00196                 return result = ss_const::instance(ss_volatile::instance(ssti->ss_const_object_get()->what_get()));
00197         default:
00198                 break;
00199         }
00200 
00201         return result = ss_volatile::create(x);
00202 }
00203 
00204 /*!
00205   Returns type representing pointer to a given type.
00206   \pre x != NULL
00207   \param x  The type to make pointer to.
00208   \return  The pointer type to the given type.  
00209  */
00210 ptr<ss_type> ss_pointer::instance(ptr<ss_type> x)
00211 {
00212         the_instances->dump_barrier_set(true); // XXX: needed just once :-I
00213 
00214         lassert(x);
00215         srp < ss_type > &result = (*the_instances)[x];
00216 
00217         if (result) 
00218                 return result;
00219 
00220         return result = ss_pointer::create(x);
00221 }
00222 
00223 /*!
00224   Returns type representing reference to a given type.
00225   \pre x != NULL
00226   \param x  The type to make reference to.
00227   \return  The  to the given type.  
00228 */
00229 ptr<ss_type> ss_reference::instance(ptr<ss_type > x)
00230 {
00231         the_instances->dump_barrier_set(true); // XXX: needed just once :-I
00232 
00233         lassert(x);
00234 
00235         ptr<ss_type2info> ssti = ss_type2info::create();
00236         x->accept_ss_type_visitor(ssti);
00237 
00238         switch (ssti->info_get()) {
00239         case ss_type2info::SS_PSEUDOREFERENCE:
00240                 lassert2(false, "Reference to pseudoreference shall not be made.");
00241                 break;
00242         case ss_type2info::SS_REFERENCE:
00243                 lassert2( 0, "FIXME: (ERRREPORT): Creating reference to a reference type" );
00244                 return NULL;
00245         default:
00246                 break;
00247         }
00248 
00249         srp<ss_type> &result = (*the_instances)[x];
00250 
00251         if (result)
00252                 return result;
00253 
00254         return result = ss_reference::create(x);
00255 }
00256 
00257 /*!
00258   Returns type representing pseudoreference to a given type.
00259   \pre x != NULL
00260   \param x  The type to make pseudoreference to.
00261   \return  The  to the given type.  
00262 */
00263 ptr<ss_type> ss_pseudoreference::instance(ptr < ss_type > x)
00264 {
00265         the_instances->dump_barrier_set(true); // XXX: needed just once :-I
00266 
00267         lassert(x);
00268 
00269         ptr<ss_type2info> ssti = ss_type2info::create();
00270 
00271         switch (ssti->process(x)) {
00272         case ss_type2info::SS_REFERENCE:
00273         case ss_type2info::SS_PSEUDOREFERENCE:
00274                 return x;
00275         default:
00276                 break;
00277         }
00278 
00279         srp<ss_type> &result = (*the_instances)[x];
00280 
00281         if (result)
00282                 return result;
00283 
00284         return result = ss_pseudoreference::create(x);
00285 }
00286 
00287 /*!
00288  * Check is this class is ancestor of its parameter
00289  */
00290 bool ss_class::is_ancestor(ptr< ss_class > descendant)
00291 {
00292         typedef ::lestes::std::list< srp< ss_class > > classlist;
00293         ptr< classlist > lst = classlist::create();
00294         ::lestes::std::list< srp< ss_class > >::iterator it_cl;
00295         ::lestes::std::list< srp< ss_base_specifier > >::iterator it;
00296 
00297         /* push 1st level of bases into list */
00298         for(it = descendant->bases_get()->begin(); it!= descendant->bases_get()->end(); it++) {
00299                 lst->push_back((*it)->base_class_get());
00300                 /* have we found ourselves? */
00301                 if ((*it)->base_class_get() == this) 
00302                         return true;
00303         }
00304                 
00305         /* for every class in the list, push into list all bases */
00306         for(it_cl = lst->begin(); it_cl != lst->end(); it_cl++){
00307                 for(it = (*it_cl)->bases_get()->begin(); it != (*it_cl)->bases_get()->end(); it_cl++) {
00308                         lst->push_back((*it)->base_class_get());
00309                         /* have we found ourselves? */
00310                         if ((*it)->base_class_get() == this)
00311                                 return true;
00312                 }
00313         }
00314         return false;
00315         
00316 }
00317 
00318 /*!
00319   Returns type representing array of a given type.
00320   \pre type != NULL
00321   \param size  The size of the array.
00322   \param type  The base type for the array.
00323   \return  The array of the given type.  
00324 */
00325 ptr<ss_type> ss_array::instance(t_size size, ptr<ss_type> type)
00326 {
00327         the_instances->dump_barrier_set(true); // XXX: needed just once :-I
00328 
00329         lassert(type);
00330 
00331         ptr < pair < t_size, srp < ss_type > > > twin = pair < t_size, srp < ss_type > >::create(size,type);
00332         srp < ss_type > & result = (*the_instances)[twin];
00333         
00334         if (result)
00335                 return result;
00336         
00337         return result = ss_array::create(size, type);
00338 }
00339 
00340 /*!
00341   Returns type representing member pointer to a given type in a given base.
00342   \pre base_type != NULL
00343   \pre element_type != NULL
00344   \param base_type  The base type for the member pointer.
00345   \param element_type  The type of the element pointed to.
00346   \return  The type of member pointer of the given properties.  
00347 */
00348 ptr<ss_type> ss_member_pointer::instance(ptr<ss_type> base_type, ptr<ss_type> element_type)
00349 {
00350         the_instances->dump_barrier_set(true); // XXX: needed just once :-I
00351 
00352         lassert(base_type);
00353         lassert(element_type);
00354 
00355         ptr < pair < srp < ss_type >, srp < ss_type > > > twin = 
00356                 pair < srp < ss_type >, srp < ss_type > >::create(base_type, element_type);
00357         srp < ss_type > & result = (*the_instances)[twin];
00358 
00359         if (result)
00360                 return result;
00361         
00362         return result = ss_member_pointer::create(base_type, element_type);
00363 }
00364 
00365 /*!
00366   Compares to other ss_function in the defined ordering. Used for container comparator.
00367   The ordering considers (in this order) the first of the following to compare less:
00368   the ellipsis flag, the return value, and the parameter sequence.
00369   For the purpose of comparison, the value of the pointer determines the ordering for
00370   the objects representing data types, as these are all singletonized SS types and thus
00371   impose consistent ordering. The parameters are compared lexicographically in the usual manner,
00372   stopping at the first inequality. If there is none, the shorter sequence compares less.
00373   \pre other != NULL
00374   \param other  The other instance to compare to.
00375   \return true  If this instance is less than the other in the defined ordering.
00376 */
00377 bool ss_function::less_than(ptr<ss_function> other)
00378 {
00379         lassert(other);
00380         
00381         if (ellipsis_get() != other->ellipsis_get())
00382                 return ellipsis_get() < other->ellipsis_get();
00383 
00384         if (returns_get() != other->returns_get())
00385                 return returns_get() < other->returns_get();
00386 
00387         typedef ::lestes::std::list< srp<ss_type> > ss_type_list;
00388         ptr<ss_type_list> p = params_get();
00389         ptr<ss_type_list> q = other->params_get();
00390 
00391         ss_type_list::iterator pi = p->begin(), qi = q->begin(), pe = p->end(), qe = q->end();
00392         for ( ; pi != pe && qi != qe; ++pi, ++qi) {
00393                 if (*pi != *qi)
00394                         return *pi < *qi;
00395         }
00396 
00397         // less when the other parameter list is longer
00398         return pi == pe && qi != qe;
00399 }
00400 
00401 /*!
00402   Compares signatures ss_function in the defined ordering.
00403   Both functions have the same signature, if both have or have no ellipsis,
00404   if the parameter type sequences have the same length and
00405   the corresponding parameter types are the same.
00406   \pre other != NULL
00407   \param other  The other instance to compare to.
00408   \return true  If this instance has the same signature.
00409 */
00410 bool ss_function::equal_signature(ptr<ss_function> other)
00411 {
00412         lassert(other);
00413 
00414         if (ellipsis_get() != other->ellipsis_get())
00415                 return false;
00416 
00417         typedef ::lestes::std::list< srp<ss_type> > ss_type_list;
00418         ptr<ss_type_list> p = params_get();
00419         ptr<ss_type_list> q = other->params_get();
00420 
00421         if (p->size() != q->size()) return false;
00422 
00423         for (ss_type_list::iterator pi = p->begin(), qi = q->begin(), pe = p->end(), qe = q->end();
00424                 pi != pe && qi != qe; ++pi, ++qi) {
00425                 if (*pi != *qi) return false;
00426         }
00427 
00428         return true;
00429 }
00430 
00431 
00432 /*
00433   Returns type representing function returning given type with given arguments.
00434   \pre returns != NULL
00435   \pre params != NULL
00436   \param return_type  The type of the return value.
00437   \param param_types  The types of the parameters.
00438   \param ellipsis  The ellipsis flag.
00439   \return  The type of function with the given properties.
00440 */
00441 ptr<ss_type> ss_function::instance(ptr<ss_type> return_type, ptr< list< srp<ss_type> > > param_types, bool ellipsis)
00442 {
00443         instances->dump_barrier_set(true); // XXX: needed just once :-I
00444 
00445         lassert(return_type);
00446         lassert(param_types);
00447 
00448         ptr<ss_function> fun = ss_function::create(return_type,param_types,ellipsis);
00449 
00450         ::std::pair< set< srp<ss_function> >::iterator, bool> result = instances->insert(fun);
00451 
00452         // return the original value, duplicate is not inserted
00453         return *(result.first);
00454 }
00455 
00456 /*!
00457   Compares two ss_function object with less_than method.
00458   \pre left != NULL
00459   \pre right != NULL
00460   \param left  The left argument for the comparison.
00461   \param right  The right argument for the comparison.
00462   \return  The result of call of left->less_than(right).
00463 */
00464 bool ss_function_comparator::operator()(const ptr<ss_function> &left, const ptr<ss_function> &right) const
00465 {
00466         lassert(left && right);
00467         return left->less_than(right);
00468 }
00469 
00470 /*!
00471   Creates the comparator.
00472 */
00473 ss_function_comparator::ss_function_comparator(void)
00474 {
00475 }
00476 
00477 end_package(sem);
00478 end_package(cplus);
00479 end_package(lang);
00480 end_package(lestes);
00481 

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