hinter.cc

Go to the documentation of this file.
00001 /*
00002    The lestes compiler suite
00003    Copyright (C) 2002, 2003, 2004, 2005 Miroslav Tichy
00004    Copyright (C) 2002, 2003, 2004, 2005 Petr Zika
00005    Copyright (C) 2002, 2003, 2004, 2005 Vojtech Hala
00006    Copyright (C) 2002, 2003, 2004, 2005 Jiri Kosina
00007    Copyright (C) 2002, 2003, 2004, 2005 Pavel Sanda
00008    Copyright (C) 2002, 2003, 2004, 2005 Jan Zouhar
00009    Copyright (C) 2002, 2003, 2004, 2005 Rudolf Thomas
00010 
00011    This program is free software; you can redistribute it and/or modify
00012    it under the terms of the GNU General Public License as published by
00013    the Free Software Foundation; version 2 of the License.
00014 
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019 
00020    See the full text of the GNU General Public License version 2, and
00021    the limitations in the file doc/LICENSE.
00022 
00023    By accepting the license the licensee waives any and all claims
00024    against the copyright holder(s) related in whole or in part to the
00025    work, its use, and/or the inability to use it.
00026  
00027  */
00028 #include <lestes/lang/cplus/sem/as_decl.g.hh>
00029 #include <lestes/lang/cplus/sem/lu_filter.g.hh>
00030 #include <lestes/lang/cplus/sem/lu_lu.g.hh>
00031 #include <lestes/lang/cplus/sem/sa_context.g.hh>
00032 #include <lestes/lang/cplus/sem/ss_declaration.g.hh>
00033 #include <lestes/lang/cplus/sem/ss_declaration_visitor.v.g.hh>
00034 #include <lestes/lang/cplus/sem/ss_decl_name.g.hh>
00035 #include <lestes/lang/cplus/sem/ss_misc.g.hh>
00036 #include <lestes/lang/cplus/sem/ss_type.g.hh>
00037 #include <lestes/lang/cplus/syn/errors.m.hh>
00038 #include <lestes/lang/cplus/syn/hinter_actions.g.hh>
00039 #include <lestes/lang/cplus/syn/hinter.g.hh>
00040 #include <lestes/lang/cplus/syn/hinter.hh>
00041 #include <lestes/lang/cplus/syn/manager.hh>
00042 #include <lestes/lang/cplus/syn/syn.hh>
00043 #include <lestes/lang/cplus/syn/token.hh>
00044 #include <lestes/msg/logger.hh>
00045 #include <lestes/std/list.hh>
00046 
00047 package(lestes);
00048 package(lang);
00049 package(cplus);
00050 package(syn);
00051 
00052 declare_logger( hl );
00053 initialize_logger( hl, "hinter", syn_logger );
00054 
00055 hinter::mode_type hinter::mode = HINTER_NORMAL;
00056 ::std::map<bison_token::hint_type,bison_token::yytokentype> hinter::id_hint2tok_type_map;
00057 
00058 using ::lestes::lang::cplus::sem::declaration_set_type;
00059 using ::lestes::lang::cplus::sem::lu_elaborated_filter;
00060 using ::lestes::lang::cplus::sem::lu_filter;
00061 using ::lestes::lang::cplus::sem::lu_func_cont_filter;
00062 using ::lestes::lang::cplus::sem::lu_lookup;
00063 using ::lestes::lang::cplus::sem::lu_multi_filter;
00064 using ::lestes::lang::cplus::sem::lu_name_filter;
00065 using ::lestes::lang::cplus::sem::lu_namespace_filter;
00066 using ::lestes::lang::cplus::sem::lu_params;
00067 using ::lestes::lang::cplus::sem::lu_qual_filter;
00068 using ::lestes::lang::cplus::sem::lu_visible_filter;
00069 using ::lestes::lang::cplus::sem::sa_context_manager;
00070 using ::lestes::lang::cplus::sem::ss_decl_name;
00071 using ::lestes::lang::cplus::sem::ss_decl_seq;
00072 using ::lestes::lang::cplus::sem::ss_declaration;
00073 using ::lestes::lang::cplus::sem::ss_declaration_time;
00074 using ::lestes::lang::cplus::sem::ss_dummy_name;
00075 using ::lestes::lang::cplus::sem::ss_ordinary_name;
00076 
00077 class one_hinter : public object {
00078 public:
00079         class state_type : public object {
00080         private:
00081 //F//           srp<ss_decl_seq> forced_scope;
00082                 srp<ss_decl_seq> qual_scope;
00083                 srp<elab_spec_key> elab_spec;
00084                 bool namespace_mode;
00085         protected:
00086                 state_type()
00087 //F//                   : forced_scope(NULL),
00088                         : qual_scope(NULL), elab_spec(NULL),
00089                         namespace_mode(false)
00090                 {}
00091                 //! copy-constructor
00092                 state_type( const ptr<state_type> & other )
00093 //F//                   : forced_scope( other->forced_scope ),
00094                         : qual_scope( other->qual_scope ),
00095                         elab_spec( other->elab_spec ),
00096                         namespace_mode( other->namespace_mode )
00097                 {}
00098                 void gc_mark()
00099                 {
00100 //F//                   forced_scope.gc_mark();
00101                         qual_scope.gc_mark();
00102                         elab_spec.gc_mark();
00103                         object::gc_mark();
00104                 }
00105         public:
00106                 static ptr<state_type> create()
00107                 {
00108                         return new state_type();
00109                 }
00110                 //! copy-constructor-like factory method
00111                 static ptr<state_type> create( const ptr<state_type> & other )
00112                 {
00113                         return new state_type( other );
00114                 }
00115 
00116 //F//           void forced_scope_set( const ptr<ss_decl_seq> & s )
00117 //F//           {
00118 //F//                   forced_scope = s;
00119 //F//           }
00120                 void qual_scope_set( const ptr<ss_decl_seq> & s )
00121                 {
00122                         qual_scope = s;
00123                 }
00124                 void elab_spec_set( const ptr<elab_spec_key> & a_elab_spec )
00125                 {
00126                         elab_spec = a_elab_spec;
00127                 }
00128                 void namespace_mode_set( bool b )
00129                 {
00130                         namespace_mode = b;
00131                 }
00132                 
00133 //F//           ptr<ss_decl_seq> forced_scope_get() const
00134 //F//           {
00135 //F//                   return checked(forced_scope);
00136 //F//           }
00137                 ptr<ss_decl_seq> qual_scope_get() const
00138                 {
00139                         return qual_scope;
00140                 }
00141                 ptr<elab_spec_key> elab_spec_get() const
00142                 {
00143                         return elab_spec;
00144                 }
00145                 bool namespace_mode_get() const
00146                 {
00147                         return namespace_mode;
00148                 }
00149         };
00150 private:
00151         srp< list< srp<state_type> > > state_stack;
00152 protected:
00153         one_hinter() : state_stack( list< srp<state_type> >::create() )
00154         {
00155                 state_stack->push_back( state_type::create() );
00156         }
00157         void gc_mark()
00158         {
00159                 state_stack.gc_mark();
00160                 object::gc_mark();
00161         }
00162 public:
00163         static ptr<one_hinter> create()
00164         {
00165                 return new one_hinter();
00166         }
00167 
00168         //! Copies current state and pushed in onto the stack (which makes it current).
00169         void push_state()
00170         {
00171                 state_stack->push_back( state_type::create( state_stack->back() ) );
00172         }
00173         void pop_state()
00174         {
00175                 lassert( !state_stack->empty() );
00176                 state_stack->pop_back();
00177                 lassert( !state_stack->empty() );
00178         }
00179 
00180 //F//   void forced_scope_set( const ptr<ss_decl_seq> & s )
00181 //F//   {
00182 //F//           lassert( !state_stack->empty() );
00183 //F//           state_stack->back()->forced_scope_set( s );
00184 //F//   }
00185         void qual_scope_set( const ptr<ss_decl_seq> & s )
00186         {
00187                 lassert( !state_stack->empty() );
00188                 state_stack->back()->qual_scope_set( s );
00189         }
00190         void elab_spec_set( const ptr<elab_spec_key> & es )
00191         {
00192                 lassert( !state_stack->empty() );
00193                 state_stack->back()->elab_spec_set( es );
00194         }
00195         void namespace_mode_set( bool b )
00196         {
00197                 lassert( !state_stack->empty() );
00198                 state_stack->back()->namespace_mode_set( b );
00199         }
00200 
00201 //F//   ptr<ss_decl_seq> forced_scope_get() const
00202 //F//   {
00203 //F//           lassert( !state_stack->empty() );
00204 //F//           return state_stack->back()->forced_scope_get();
00205 //F//   }
00206         ptr<ss_decl_seq> qual_scope_get() const
00207         {
00208                 lassert( !state_stack->empty() );
00209                 return state_stack->back()->qual_scope_get();
00210         }
00211         ptr<elab_spec_key> elab_spec_get() const
00212         {
00213                 lassert( !state_stack->empty() );
00214                 return state_stack->back()->elab_spec_get();
00215         }
00216         bool namespace_mode_get() const
00217         {
00218                 lassert( !state_stack->empty() );
00219                 return state_stack->back()->namespace_mode_get();
00220         }
00221 };
00222 
00223 typedef list< srp<one_hinter> > hinter_stack_type;
00224 static ptr<hinter_stack_type> hinter_stack;
00225 
00226 void spawn_hinter_action::run()
00227 {
00228         hinter_stack->push_back( one_hinter::create() );
00229 }
00230 
00231 void close_hinter_action::run()
00232 {
00233         lassert( !hinter_stack->empty() );
00234         hinter_stack->pop_back();
00235         lassert( !hinter_stack->empty() );
00236 }
00237 
00238 void push_state_action::run()
00239 {
00240         lassert( !hinter_stack->empty() );
00241         hinter_stack->back()->push_state();
00242 }
00243 
00244 void pop_state_action::run()
00245 {
00246         lassert( !hinter_stack->empty() );
00247         hinter_stack->back()->pop_state();
00248 }
00249 
00250 /*!
00251  * \pre Manager must be already initialized, as this method installs hooks into it.
00252  */
00253 void hinter::init( mode_type a_mode )
00254 {
00255         lassert2( id_hint2tok_type_map.empty(),
00256                         "Trying to initialize hinter for the second time." );
00257 
00258         mode = a_mode;
00259 
00260         hinter_stack = hinter_stack_type::create();
00261         hinter_stack->push_back( one_hinter::create() );
00262 
00263         id_hint2tok_type_map[ bison_token::HINT_TEMPL_NONTYPE ]
00264                 = bison_token::_TEMPL_NONTYPE;
00265         id_hint2tok_type_map[ bison_token::HINT_TEMPL_TYPE ]
00266                 = bison_token::_TEMPL_TYPE;
00267         id_hint2tok_type_map[ bison_token::HINT_NONTYPE ]
00268                 = bison_token::_NONTYPE;
00269         id_hint2tok_type_map[ bison_token::HINT_CLASS ]
00270                 = bison_token::_CLASS_NAME_ID;
00271         id_hint2tok_type_map[ bison_token::HINT_ENUM ]
00272                 = bison_token::_ENUM_NAME_ID;
00273         id_hint2tok_type_map[ bison_token::HINT_TYPEDEF ]
00274                 = bison_token::_TYPEDEF_NAME_ID;
00275         id_hint2tok_type_map[ bison_token::HINT_NAMESPACE ]
00276                 = bison_token::_NMSPC_NAME;
00277         id_hint2tok_type_map[ bison_token::HINT_UNKNOWN ]
00278                 = bison_token::_UNKNOWN_ID;
00279 
00280         manager::spawn_event->attach( spawn_hinter_action::instance() );
00281         manager::close_event->attach( close_hinter_action::instance() );
00282 
00283         manager::start_event->attach( push_state_action::instance() );
00284         manager::commit_event->attach( pop_state_action::instance() );
00285         manager::rollback_event->attach( pop_state_action::instance() );
00286 }
00287 
00288 hinter::mode_type hinter::mode_get()
00289 {
00290         return mode;
00291 }
00292 
00293 ptr<bison_token> hinter::use_user_hint( const ptr<bison_token> & t )
00294 {
00295         lassert( t->user_hint_get() != bison_token::HINT_NONE );
00296         int result_type = id_hint2tok_type_map[ t->user_hint_get() ];
00297         lassert2( result_type != 0,
00298                         "Either got invalid hint, or the map is corrupted." );
00299 
00300         return bison_id_token::create( result_type, t->wrapped_token_get(),
00301                         bison_id_token::BY_USER,
00302                         declaration_set_type::create() );
00303 }
00304 
00305 static ptr<declaration_set_type> unqualified( const ptr<ss_decl_name> & name, const ptr<ss_decl_seq> & seq )
00306 {
00307         static ptr<lu_params> params;
00308         static ptr<lu_name_filter> name_filter;
00309         static ptr<lu_visible_filter> visible_filter;
00310         if (!params) {
00311                 ptr<lu_multi_filter> big_filter = lu_multi_filter::create();
00312                 params = lu_params::create( lu_params::UDIR_ALWAYS,
00313                                 lu_params::UDECL_RESOLVE_BEFORE_FILTER,
00314                                 lu_params::SEARCH_PARENTS,
00315                                 ss_declaration_time::infinity(), big_filter );
00316                 name_filter = lu_name_filter::create( name );
00317                 big_filter->add_filter( name_filter );
00318                 big_filter->add_filter( lu_func_cont_filter::instance() );
00319                 visible_filter = lu_visible_filter::create( ss_declaration_time::infinity() );
00320                 big_filter->add_filter( visible_filter );
00321         }
00322         // the location -> time translation should be made easier...
00323         ptr<ss_declaration_time> time = ss_declaration_time::create( name->location_get()->order_get() );
00324         params->time_set( time );
00325         visible_filter->visible_before_set( time );
00326         name_filter->name_set( name );
00327         return lu_lookup::instance()->main( seq, params );
00328 }
00329 
00330 static ptr<declaration_set_type> unqualified_elab( const ptr<ss_decl_name> & name, const ptr<ss_decl_seq> & seq )
00331 {
00332         static ptr<lu_params> params;
00333         static ptr<lu_name_filter> name_filter;
00334         static ptr<lu_visible_filter> visible_filter;
00335         if (!params) {
00336                 ptr<lu_multi_filter> big_filter = lu_multi_filter::create();
00337                 params = lu_params::create( lu_params::UDIR_ALWAYS,
00338                                 lu_params::UDECL_RESOLVE_BEFORE_FILTER,
00339                                 lu_params::SEARCH_PARENTS,
00340                                 ss_declaration_time::infinity(), big_filter );
00341                 name_filter = lu_name_filter::create( name );
00342                 big_filter->add_filter( name_filter );
00343                 big_filter->add_filter( lu_elaborated_filter::instance() );
00344                 visible_filter = lu_visible_filter::create( ss_declaration_time::infinity() );
00345                 big_filter->add_filter( visible_filter );
00346         }
00347         // the location -> time translation should be made easier...
00348         ptr<ss_declaration_time> time = ss_declaration_time::create( name->location_get()->order_get() );
00349         params->time_set( time );
00350         visible_filter->visible_before_set( time );
00351         name_filter->name_set( name );
00352         return lu_lookup::instance()->main( seq, params );
00353 }
00354 
00355 static ptr<declaration_set_type> look_first( const ptr<ss_decl_name> & name, const ptr<ss_decl_seq> & seq )
00356 {
00357         static ptr<lu_params> params;
00358         static ptr<lu_name_filter> name_filter;
00359         static ptr<lu_visible_filter> visible_filter;
00360         if (!params) {
00361                 ptr<lu_multi_filter> big_filter = lu_multi_filter::create();
00362                 // XXX: really UDIR_ALWAYS ???
00363                 params = lu_params::create( lu_params::UDIR_ALWAYS,
00364                                 lu_params::UDECL_RESOLVE_BEFORE_FILTER,
00365                                 lu_params::SEARCH_PARENTS,
00366                                 ss_declaration_time::infinity(), big_filter );
00367                 name_filter = lu_name_filter::create( name );
00368                 big_filter->add_filter( name_filter );
00369                 big_filter->add_filter( lu_qual_filter::instance() );
00370                 visible_filter = lu_visible_filter::create( ss_declaration_time::infinity() );
00371                 big_filter->add_filter( visible_filter );
00372         }
00373         // the location -> time translation should be made easier...
00374         ptr<ss_declaration_time> time = ss_declaration_time::create( name->location_get()->order_get() );
00375         params->time_set( time );
00376         visible_filter->visible_before_set( time );
00377         name_filter->name_set( name );
00378         return lu_lookup::instance()->main( seq, params );
00379 }
00380 
00381 static ptr<declaration_set_type> look_last( const ptr<ss_decl_name> & name, const ptr<ss_decl_seq> & seq )
00382 {
00383         static ptr<lu_params> params;
00384         static ptr<lu_name_filter> name_filter;
00385         static ptr<lu_visible_filter> visible_filter;
00386         if (!params) {
00387                 ptr<lu_multi_filter> big_filter = lu_multi_filter::create();
00388                 params = lu_params::create( lu_params::UDIR_FALLBACK,
00389                                 lu_params::UDECL_RESOLVE_BEFORE_FILTER,
00390                                 lu_params::SKIP_PARENTS,
00391                                 ss_declaration_time::infinity(), big_filter );
00392                 name_filter = lu_name_filter::create( name );
00393                 big_filter->add_filter( name_filter );
00394                 big_filter->add_filter( lu_func_cont_filter::instance() );
00395                 visible_filter = lu_visible_filter::create( ss_declaration_time::infinity() );
00396                 big_filter->add_filter( visible_filter );
00397         }
00398         // the location -> time translation should be made easier...
00399         ptr<ss_declaration_time> time = ss_declaration_time::create( name->location_get()->order_get() );
00400         params->time_set( time );
00401         visible_filter->visible_before_set( time );
00402         name_filter->name_set( name );
00403         return lu_lookup::instance()->main( seq, params );
00404 }
00405 
00406 static ptr<declaration_set_type> look_last_elab( const ptr<ss_decl_name> & name, const ptr<ss_decl_seq> & seq )
00407 {
00408         static ptr<lu_params> params;
00409         static ptr<lu_name_filter> name_filter;
00410         static ptr<lu_visible_filter> visible_filter;
00411         if (!params) {
00412                 ptr<lu_multi_filter> big_filter = lu_multi_filter::create();
00413                 params = lu_params::create( lu_params::UDIR_FALLBACK,
00414                                 lu_params::UDECL_RESOLVE_BEFORE_FILTER,
00415                                 lu_params::SKIP_PARENTS,
00416                                 ss_declaration_time::infinity(), big_filter );
00417                 name_filter = lu_name_filter::create( name );
00418                 big_filter->add_filter( name_filter );
00419                 big_filter->add_filter( lu_elaborated_filter::instance() );
00420                 visible_filter = lu_visible_filter::create( ss_declaration_time::infinity() );
00421                 // we _want_ to see invisible classes in elaborated type specifiers
00422                 // big_filter->add_filter( visible_filter );
00423         }
00424         // the location -> time translation should be made easier...
00425         ptr<ss_declaration_time> time = ss_declaration_time::create( name->location_get()->order_get() );
00426         params->time_set( time );
00427         visible_filter->visible_before_set( time );
00428         name_filter->name_set( name );
00429         return lu_lookup::instance()->main( seq, params );
00430 }
00431 
00432 static ptr<declaration_set_type> middle( const ptr<ss_decl_name> & name, const ptr<ss_decl_seq> & seq )
00433 {
00434         static ptr<lu_params> params;
00435         static ptr<lu_name_filter> name_filter;
00436         static ptr<lu_visible_filter> visible_filter;
00437         if (!params) {
00438                 ptr<lu_multi_filter> big_filter = lu_multi_filter::create();
00439                 params = lu_params::create( lu_params::UDIR_FALLBACK,
00440                                 lu_params::UDECL_RESOLVE_BEFORE_FILTER,
00441                                 lu_params::SKIP_PARENTS,
00442                                 ss_declaration_time::infinity(), big_filter );
00443                 name_filter = lu_name_filter::create( name );
00444                 big_filter->add_filter( name_filter );
00445                 big_filter->add_filter( lu_qual_filter::instance() );
00446                 visible_filter = lu_visible_filter::create( ss_declaration_time::infinity() );
00447                 big_filter->add_filter( visible_filter );
00448         }
00449         // the location -> time translation should be made easier...
00450         ptr<ss_declaration_time> time = ss_declaration_time::create( name->location_get()->order_get() );
00451         params->time_set( time );
00452         visible_filter->visible_before_set( time );
00453         name_filter->name_set( name );
00454         return lu_lookup::instance()->main( seq, params );
00455 }
00456 
00457 static ptr<declaration_set_type> nmspace( const ptr<ss_decl_name> & name, const ptr<ss_decl_seq> & seq )
00458 {
00459         static ptr<lu_params> params;
00460         static ptr<lu_name_filter> name_filter;
00461         if (!params) {
00462                 ptr<lu_multi_filter> big_filter = lu_multi_filter::create();
00463                 params = lu_params::create( lu_params::UDIR_IGNORE,
00464                                 lu_params::UDECL_RESOLVE_BEFORE_FILTER,
00465                                 lu_params::SKIP_PARENTS,
00466                                 ss_declaration_time::infinity(), big_filter );
00467                 name_filter = lu_name_filter::create( name );
00468                 big_filter->add_filter( name_filter );
00469 // deliberately commented out:
00470 //              big_filter->add_filter( lu_namespace_filter::instance() );
00471         }
00472         // the location -> time translation should be made easier...
00473         ptr<ss_declaration_time> time = ss_declaration_time::create( name->location_get()->order_get() );
00474         params->time_set( time );
00475         name_filter->name_set( name );
00476         return lu_lookup::instance()->main( seq, params );
00477 }
00478 
00479 ptr<bison_token> hinter::compute_hint( const ptr<bison_token> & t,
00480                 const ptr<bison_token> & lookahead )
00481 {
00482         lassert( t && lookahead );
00483 
00484         ptr<ss_decl_seq> qual_scope = qual_scope_get();
00485         ptr<elab_spec_key> elab_spec = elab_spec_get();
00486 
00487         bool first = !qual_scope;       // first -- there was no qualification
00488         bool last = lookahead->type_get() != bison_token::TOK_COLON_COLON;
00489         bool ns_mode = namespace_mode_get();
00490 
00491         ptr<ss_ordinary_name> name = ss_ordinary_name::create( t->location_get(), t->value_get() );
00492 
00493         ptr<ss_decl_seq> seq;
00494         if (qual_scope)
00495                 seq = qual_scope;
00496         else
00497                 seq = sa_context_manager::instance()->current()->ss_get()->scope_get();
00498                 // was:
00499                 //seq = forced_scope_get();
00500 
00501         // first && last -> unqualified identifier
00502         // first && !last -> first part of qualification
00503         // !first && last -> last part in qualified name
00504         // !first && !last -> middle part in qualification
00505 
00506         // elab_spec is considered only when last == true
00507 
00508         llog(hl) << "first: " << first << " last: " << last << " elab_spec: " << bool(elab_spec) << "\n";
00509 
00510         ptr<declaration_set_type> lookup_result;
00511 
00512         if (ns_mode && !qual_scope)
00513                 lookup_result = nmspace( name, seq );
00514         else if (ns_mode && qual_scope)
00515                 lassert2( false, "Not implemented yet." );
00516         else if (first && last && !elab_spec)
00517                 lookup_result = unqualified( name, seq );
00518         else if (first && last && elab_spec)
00519                 lookup_result = unqualified_elab( name, seq );
00520         else if (first && !last)
00521                 lookup_result = look_first( name, seq );
00522         else if (!first && last && !elab_spec)
00523                 lookup_result = look_last( name, seq );
00524         else if (!first && last && elab_spec)
00525                 lookup_result = look_last_elab( name, seq );
00526         else if (!first && !last)
00527                 lookup_result = middle( name, seq );
00528         lassert(lookup_result);
00529 
00530         llog(hl) << "lookup_result->size(): " << lookup_result->size() << "\n";
00531 
00532         int result_token_type = hint_from_declaration_set::instance()->process( lookup_result );
00533 
00534         // [3.4.3/1] class or namespacename must be found before "non-global" :: operator
00535         if (!last && result_token_type != bison_token::_CLASS_NAME_ID
00536                         && result_token_type != bison_token::_NMSPC_NAME) {
00537                 if (result_token_type == bison_token::_UNKNOWN_ID)
00538                         report << unknown_before_coloncolon << t->location_get();
00539                 else
00540                         report << wrong_before_coloncolon << t->location_get();
00541         }
00542 
00543         /* when we got typedef name *not* prefixed by class-key/enum, see if it is a class name */
00544         if (result_token_type == bison_token::_TYPEDEF_NAME_ID && !elab_spec) {
00545                 lookup_result = typedef_class_resolver::instance()->process( lookup_result );
00546                 result_token_type =
00547                         hint_from_declaration_set::instance()->process( lookup_result );
00548         }
00549 
00550         namespace_mode_set(false);
00551         qual_scope_set(NULL);
00552         if (last)
00553                 elab_spec_set(NULL);
00554 
00555         ptr<bison_token> result = bison_id_token::create( result_token_type,
00556                 t->wrapped_token_get(), bison_id_token::BY_HINTER, lookup_result );
00557 
00558         llog(hl) << "computed " << result << "\n";
00559 
00560         return result;
00561 }
00562 
00563 ptr<bison_token> hinter::hint( const ptr<bison_token> & t, const ptr<bison_token> & lookahead )
00564 {
00565         lassert( t && lookahead );
00566 
00567         llog(hl) << "hinter::hint( " << t << " ; la: " << lookahead << " ) called\n";
00568 
00569         lassert2( t->type_get() == bison_token::TOK_IDENT,
00570                         "Hinter called on non-identifier token." );
00571 
00572         bool is_user_hinted = t->user_hint_get() != bison_token::HINT_NONE;
00573 
00574         ptr<bison_token> result;
00575 
00576         switch (mode) {
00577         case HINTER_OFF:
00578                 lassert2( is_user_hinted, "Got unhinted identifier." );
00579                 result = use_user_hint(t);
00580                 break;
00581         case HINTER_USER:
00582                 if (is_user_hinted)
00583                         result = use_user_hint(t);
00584                 else
00585                         result = compute_hint( t, lookahead );
00586                 break;
00587         case HINTER_CHECK:
00588                 result = compute_hint( t, lookahead );
00589                 if (is_user_hinted) {
00590                         ptr<bison_token> by_user = use_user_hint(t);
00591                         lassert2( by_user->type_get() == result->type_get(),
00592                                 "User and computed hint do not agree." );
00593                 }
00594                 break;
00595         case HINTER_NORMAL:
00596                 result = compute_hint( t, lookahead );
00597                 break;
00598         }
00599 
00600         return checked(result);
00601 }
00602 
00603 //F//ptr<ss_decl_seq> hinter::forced_scope_get()
00604 //F//{
00605 //F//   lassert( !hinter_stack->empty() );
00606 //F//   return hinter_stack->back()->forced_scope_get();
00607 //F//}
00608 
00609 ptr<ss_decl_seq> hinter::qual_scope_get()
00610 {
00611         lassert( !hinter_stack->empty() );
00612         return hinter_stack->back()->qual_scope_get();
00613 }
00614 
00615 ptr<elab_spec_key> hinter::elab_spec_get()
00616 {
00617         lassert( !hinter_stack->empty() );
00618         return hinter_stack->back()->elab_spec_get();
00619 }
00620 
00621 bool hinter::namespace_mode_get()
00622 {
00623         lassert( !hinter_stack->empty() );
00624         return hinter_stack->back()->namespace_mode_get();
00625 }
00626 
00627 //F//void hinter::forced_scope_set( const ptr<ss_decl_seq> & ds )
00628 //F//{
00629 //F//   lassert( !hinter_stack->empty() );
00630 //F//   hinter_stack->back()->forced_scope_set(ds);
00631 //F//}
00632 
00633 void hinter::qual_scope_set( const ptr<ss_decl_seq> & ds )
00634 {
00635         lassert( !hinter_stack->empty() );
00636         hinter_stack->back()->qual_scope_set(ds);
00637 }
00638 
00639 void hinter::elab_spec_set( const ptr<elab_spec_key> & es )
00640 {
00641         lassert( !hinter_stack->empty() );
00642         hinter_stack->back()->elab_spec_set(es);
00643 }
00644 
00645 void hinter::namespace_mode_set( bool b )
00646 {
00647         lassert( !hinter_stack->empty() );
00648         hinter_stack->back()->namespace_mode_set( b );
00649 }
00650 
00651 void hinter::qual_scope_set_root()
00652 {
00653         qual_scope_set( ss_decl_seq::root_instance() );
00654 }
00655 
00656 using ::lestes::lang::cplus::sem::ss_namespace_definition;
00657 using ::lestes::lang::cplus::sem::ss_object_declaration;
00658 using ::lestes::lang::cplus::sem::ss_bitfield_declaration;
00659 using ::lestes::lang::cplus::sem::ss_parameter_declaration;
00660 using ::lestes::lang::cplus::sem::ss_fake_declaration;
00661 using ::lestes::lang::cplus::sem::ss_injected_class_declaration;
00662 using ::lestes::lang::cplus::sem::ss_enum_definition;
00663 using ::lestes::lang::cplus::sem::ss_typedef_definition;
00664 using ::lestes::lang::cplus::sem::ss_enumerator_declaration;
00665 using ::lestes::lang::cplus::sem::ss_structure_declaration;
00666 using ::lestes::lang::cplus::sem::ss_function_declaration;
00667 using ::lestes::lang::cplus::sem::ss_method_declaration;
00668 using ::lestes::lang::cplus::sem::ss_using_declaration;
00669 using ::lestes::lang::cplus::sem::ss_compound_stmt_declaration;
00670 using ::lestes::lang::cplus::sem::ss_builtin_operator_declaration;
00671 
00672 void hint_from_declaration_set::visit_ss_namespace_definition( ptr< ss_namespace_definition > )
00673 {
00674         // this type of declaration can only be alone in the set
00675         lassert( result_get() == bison_token::_UNKNOWN_ID );
00676         result_set( bison_token::_NMSPC_NAME );
00677 }
00678 
00679 void hint_from_declaration_set::visit_ss_object_declaration( ptr< ss_object_declaration > )
00680 {
00681         // this type of declaration can only be alone in the set
00682         lassert( result_get() == bison_token::_UNKNOWN_ID );
00683         result_set( bison_token::_NONTYPE );
00684 }
00685 
00686 void hint_from_declaration_set::visit_ss_bitfield_declaration( ptr< ss_bitfield_declaration > )
00687 {
00688         // this type of declaration can only be alone in the set
00689         lassert( result_get() == bison_token::_UNKNOWN_ID );
00690         result_set( bison_token::_NONTYPE );
00691 }
00692 
00693 void hint_from_declaration_set::visit_ss_parameter_declaration( ptr< ss_parameter_declaration > )
00694 {
00695         // this type of declaration can only be alone in the set
00696         lassert( result_get() == bison_token::_UNKNOWN_ID );
00697         result_set( bison_token::_NONTYPE );
00698 }
00699 
00700 void hint_from_declaration_set::visit_ss_fake_declaration( ptr< ss_fake_declaration > )
00701 {
00702         // this type of declaration can only be alone in the set
00703         lassert( result_get() == bison_token::_UNKNOWN_ID );
00704         result_set( bison_token::_NONTYPE );
00705 }
00706 
00707 void hint_from_declaration_set::visit_ss_injected_class_declaration( ptr< ss_injected_class_declaration > )
00708 {
00709         // FIXME:
00710         // FIXME: is this correct with respect to A::A::x being forbidden?
00711         // this type of declaration can only be alone in the set
00712         lassert( result_get() == bison_token::_UNKNOWN_ID );
00713         result_set( bison_token::_CLASS_NAME_ID );
00714 }
00715 
00716 void hint_from_declaration_set::visit_ss_enum_definition( ptr< ss_enum_definition > )
00717 {
00718         // this type of declaration can only be alone in the set
00719         lassert( result_get() == bison_token::_UNKNOWN_ID );
00720         result_set( bison_token::_ENUM_NAME_ID );
00721 }
00722 
00723 void hint_from_declaration_set::visit_ss_typedef_definition( ptr< ss_typedef_definition > )
00724 {
00725         // this type of declaration can only be alone in the set
00726         lassert( result_get() == bison_token::_UNKNOWN_ID );
00727         result_set( bison_token::_TYPEDEF_NAME_ID );
00728 }
00729 
00730 void hint_from_declaration_set::visit_ss_enumerator_declaration( ptr< ss_enumerator_declaration > )
00731 {
00732         // this type of declaration can only be alone in the set
00733         lassert( result_get() == bison_token::_UNKNOWN_ID );
00734         result_set( bison_token::_NONTYPE );
00735 }
00736 
00737 void hint_from_declaration_set::visit_ss_structure_declaration( ptr< ss_structure_declaration > )
00738 {
00739         // this type of declaration can only be alone in the set
00740         lassert( result_get() == bison_token::_UNKNOWN_ID );
00741         result_set( bison_token::_CLASS_NAME_ID );
00742 }
00743 
00744 void hint_from_declaration_set::visit_ss_function_declaration( ptr< ss_function_declaration > )
00745 {
00746         // allow multiple functions in the set; they cannot be mixed with other types, however
00747         lassert( result_get() == bison_token::_UNKNOWN_ID || was_function_get() );
00748         was_function_set( true );
00749         result_set( bison_token::_NONTYPE );
00750 }
00751 
00752 void hint_from_declaration_set::visit_ss_method_declaration( ptr< ss_method_declaration > )
00753 {
00754         // allow multiple functions in the set; they cannot be mixed with other types, however
00755         lassert( result_get() == bison_token::_UNKNOWN_ID || was_function_get() );
00756         was_function_set( true );
00757         result_set( bison_token::_NONTYPE );
00758 }
00759 
00760 void hint_from_declaration_set::visit_ss_using_declaration( ptr< ss_using_declaration > )
00761 {
00762         // FIXME: is this possible?!
00763         lassert( false );
00764 }
00765 
00766 void hint_from_declaration_set::visit_ss_compound_stmt_declaration( ptr< ss_compound_stmt_declaration > )
00767 {
00768         lassert( false );
00769 }
00770 
00771 void hint_from_declaration_set::visit_ss_builtin_operator_declaration( ptr< ss_builtin_operator_declaration > )
00772 {
00773         lassert( false );
00774 }
00775 
00776 int hint_from_declaration_set::process( ptr<declaration_set_type> ds )
00777 {
00778         result_set( bison_token::_UNKNOWN_ID );
00779         was_function_set( false );
00780         /* visit each of the declarations... */
00781         for ( declaration_set_type::const_iterator it = ds->begin(); it != ds->end(); ++it )
00782                 (*it)->accept_ss_declaration_visitor( ptr<ss_declaration_visitor>(this) );
00783         return result_get();
00784 }
00785 
00786 using ::lestes::lang::cplus::sem::ss_type;
00787 using ::lestes::lang::cplus::sem::ss_struct_base;
00788 using ::lestes::lang::cplus::sem::ss_class;
00789 using ::lestes::lang::cplus::sem::ss_union;
00790 
00791 ptr<declaration_set_type> typedef_class_resolver::process( ptr<declaration_set_type> ds )
00792 {
00793         lassert2( ds->size() == 1, "Typedef must have only one delcaration." );
00794 
00795         /*
00796          * if it is a struct type, sets decl to non-NULL value
00797          * otherwise sets it to NULL
00798          * */
00799         (*ds->begin())->type_get()->accept_ss_type_visitor( this );
00800 
00801         ptr<declaration_set_type> result;
00802         if (decl_get()) {
00803                 result = declaration_set_type::create();
00804                 result->insert( decl_get() );
00805         } else
00806                 result = ds;
00807 
00808         return result;
00809 }
00810 
00811 void typedef_class_resolver::default_action( ptr<ss_type> )
00812 {
00813         decl_set( NULL );
00814 }
00815 
00816 void typedef_class_resolver::visit_ss_struct_base( ptr<ss_struct_base> sb )
00817 {
00818         decl_set( sb->decl_get() );
00819 }
00820 
00821 void typedef_class_resolver::visit_ss_class( ptr<ss_class> c )
00822 {
00823         visit_ss_struct_base(c);
00824 }
00825 
00826 void typedef_class_resolver::visit_ss_union( ptr<ss_union> u )
00827 {
00828         visit_ss_struct_base(u);
00829 }
00830 
00831 end_package(syn);
00832 end_package(cplus);
00833 end_package(lang);
00834 end_package(lestes);

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