00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <lestes/common.hh>
00029 #include <lestes/lang/cplus/sem/lu_filter.g.hh>
00030 #include <lestes/lang/cplus/sem/lu_logger.hh>
00031 #include <lestes/lang/cplus/sem/lu_lu.g.hh>
00032 #include <lestes/lang/cplus/sem/ss_declaration.g.hh>
00033 #include <lestes/lang/cplus/sem/ss_decl_name.g.hh>
00034 #include <lestes/lang/cplus/sem/ss_misc.g.hh>
00035 #include <lestes/lang/cplus/sem/ss_statement.g.hh>
00036 #include <lestes/lang/cplus/sem/ss_type.g.hh>
00037 #include <lestes/lang/cplus/sem/ss_using_target.g.hh>
00038 #include <lestes/msg/logger.hh>
00039 #include <lestes/std/list.hh>
00040 #include <lestes/std/objectize_macros.hh>
00041 #include <lestes/std/pair.hh>
00042 #include <lestes/std/set.hh>
00043
00044 #include <algorithm>
00045 #include <iterator>
00046
00047 package(lestes);
00048 package(lang);
00049 package(cplus);
00050 package(sem);
00051
00052 declare_logger( lookup_log );
00053 initialize_logger( lookup_log, "lookup", lu_logger );
00054
00055 #define LOOKUP_ASSERTIONS
00056
00057 #ifdef LOOKUP_ASSERTIONS
00058 # define lookup_lassert( x ) lassert( x )
00059 # define lookup_lassert2( x, y ) lassert2( x, y )
00060
00061 static ptr<ss_decl_seq> seq_param;
00062
00063 #else
00064 # define lookup_lassert( x ) (void)0
00065 # define lookup_lassert2( x, y ) (void)0
00066 #endif
00067
00068 typedef list< srp<ss_base_specifier> > bases_type;
00069 end_package(sem);
00070 end_package(cplus);
00071 end_package(lang);
00072 package(std);
00073 specialize_objectize_nodump( ::lestes::lang::cplus::sem::bases_type::const_iterator );
00074 end_package(std);
00075 package(lang);
00076 package(cplus);
00077 package(sem);
00078
00079
00080
00081
00082
00083 ptr<declaration_set_type> lu_lookup::main( ptr<ss_decl_seq> seq, ptr<lu_params> params )
00084 {
00085 lassert( !params_get() && !visited_seqs );
00086 lassert2( params, "Lookup parameters must not be NULL." );
00087
00088 visited_seqs_set( decl_seq_set_type::create() );
00089 params_set( params );
00090
00091 bool search_parents = params->parent_search_get() == lu_params::SEARCH_PARENTS;
00092 ptr<declaration_set_type> result;
00093 do {
00094 bool not_yet_visited = visited_seqs_get()->insert(seq).second;
00095 if (not_yet_visited)
00096 result = deep_scan( seq );
00097 lassert2( result, "The very first decl_seq has been marked as already visited!" );
00098 if (seq == ss_decl_seq::root_instance())
00099 break;
00100 seq = seq->parent_get();
00101 } while (result->empty() && search_parents);
00102
00103 params_set( NULL );
00104 visited_seqs_set( NULL );
00105 return result;
00106 }
00107
00108
00109
00110
00111 static ptr<declaration_set_type> unify(
00112 const ptr<declaration_set_type> & s1,
00113 const ptr<declaration_set_type> & s2 )
00114 {
00115 ptr<declaration_set_type> result = declaration_set_type::create();
00116 ::std::set_union( s1->begin(), s1->end(), s2->begin(), s2->end(),
00117 ::std::inserter( *result, result->end() ) );
00118 return result;
00119 }
00120
00121
00122
00123
00124 ptr<declaration_set_type> lu_lookup::deep_scan( ptr<ss_decl_seq> starting_seq )
00125 {
00126 typedef list< srp<ss_decl_seq> > queue_type;
00127 typedef list< srp<ss_using_directive> > directives_type;
00128
00129 ptr<declaration_set_type> result = declaration_set_type::create();
00130
00131 ptr<queue_type> queue = queue_type::create();
00132
00133 queue->push_back( starting_seq );
00134
00135 while (!queue->empty()) {
00136 ptr<ss_decl_seq> seq = queue->front();
00137 queue->pop_front();
00138 #ifdef LOOKUP_ASSERTIONS
00139
00140 seq_param = seq;
00141 #endif
00142 ptr<declaration_set_type> local_result = lookup_by_decl( seq->declared_by_get() );
00143
00144 result = unify( result, local_result );
00145
00146 switch (params_get()->using_directives_handling_get()) {
00147 case lu_params::UDIR_IGNORE:
00148 continue;
00149 case lu_params::UDIR_FALLBACK:
00150 if (!local_result->empty())
00151 continue;
00152
00153 case lu_params::UDIR_ALWAYS:
00154 ;
00155
00156 }
00157
00158 const ptr<directives_type> & directives = seq->using_directives_get();
00159 for ( directives_type::const_iterator it = directives->begin(); it != directives->end(); ++it ) {
00160
00161
00162
00163
00164
00165 if (!(*it)->decl_time_get()->is_before( params_get()->time_get() ))
00166 break;
00167 const ptr<ss_decl_seq> & used_seq = (*it)->nspace_get()->body_get();
00168 bool not_yet_visited = visited_seqs_get()->insert(used_seq).second;
00169 if (not_yet_visited)
00170 queue->push_back(used_seq);
00171 }
00172 }
00173 return result;
00174 }
00175
00176 ptr<declaration_set_type> lu_lookup::simple_scan( ptr<ss_decl_seq> seq, ptr<lu_params> params )
00177 {
00178 ptr<declaration_set_type> result = declaration_set_type::create();
00179 typedef list< srp<ss_declaration> > contents_type;
00180 const srp<contents_type> & contents = seq->contents_get();
00181
00182 for ( contents_type::reverse_iterator it = contents->rbegin();
00183 it != contents->rend(); ++it ) {
00184
00185 ptr<ss_declaration> decl = *it;
00186 ptr<ss_declaration> real_decl;
00187
00188
00189 if (!decl->decl_time_get()->is_before( params->time_get() ))
00190 continue;
00191
00192 lu_params::using_declarations_handling_type udecl_handling =
00193 params->using_declarations_handling_get();
00194 if (udecl_handling != lu_params::UDECL_THROUGH) {
00195
00196 real_decl = ss_using_target::instance()->process(decl);
00197 if (decl != real_decl) {
00198
00199 switch (udecl_handling) {
00200 case lu_params::UDECL_IGNORE:
00201 continue;
00202 case lu_params::UDECL_RESOLVE_BEFORE_FILTER:
00203 decl = real_decl;
00204 break;
00205 default:
00206
00207 break;
00208 }
00209 }
00210 }
00211
00212 llog(lookup_log) << "calling filter on decl #" << decl->uid_get() << "\n";
00213
00214 lu_filter::result_type filt = params->filter_get()->filter(decl);
00215
00216 llog(lookup_log) << "got result " << lu_filter::result2lstring(filt) << "\n";
00217
00218 if (filt == lu_filter::FR_NO)
00219 continue;
00220
00221 if (udecl_handling == lu_params::UDECL_RESOLVE_AFTER_FILTER) {
00222 lassert( real_decl );
00223 decl = real_decl;
00224 }
00225
00226 result->insert( decl );
00227
00228 if (filt == lu_filter::FR_YES)
00229 break;
00230 }
00231 return result;
00232 }
00233
00234 ptr<declaration_set_type> lu_lookup::internal_simple_scan( ptr<ss_decl_seq> seq )
00235 {
00236 return simple_scan( seq, params_get() );
00237 }
00238
00239 void lu_lookup::default_action( ptr<ss_declaration> )
00240 {
00241 lassert2( false, "Decl_seq declared by an unknown type of declaration." );
00242 }
00243
00244 void lu_lookup::visit_ss_namespace_definition( ptr<ss_namespace_definition> nsd )
00245 {
00246 lookup_lassert( nsd->body_get() == seq_param );
00247 lookup_result_set( internal_simple_scan( nsd->body_get() ) );
00248 }
00249
00250 void lu_lookup::visit_ss_function_declaration( ptr<ss_function_declaration> fd )
00251 {
00252 lookup_lassert( fd->parameters_get() == seq_param );
00253 lookup_result_set( internal_simple_scan( fd->body_get()->decl_seq_get() ) );
00254 }
00255
00256 void lu_lookup::visit_ss_compound_stmt_declaration( ptr<ss_compound_stmt_declaration> csd )
00257 {
00258 lookup_lassert( csd->compound_stmt_get()->decl_seq_get() == seq_param );
00259 lookup_result_set( internal_simple_scan( csd->compound_stmt_get()->decl_seq_get() ) );
00260 }
00261
00262 void lu_lookup::visit_ss_structure_declaration( ptr<ss_structure_declaration> td )
00263 {
00264 lookup_result_set( lu_lookup_in_type::instance()->main( td->type_get(), params_get() ) );
00265 }
00266
00267 ptr<declaration_set_type> lu_lookup_in_type::main( ptr<ss_type> type, ptr<lu_params> params )
00268 {
00269 lassert( !params_get() );
00270 params_set( checked(params) );
00271
00272 ptr<declaration_set_type> result = lookup_by_type( type );
00273
00274 params_set( NULL );
00275
00276 return result;
00277 }
00278
00279 ptr<declaration_set_type> lu_lookup_in_type::internal_simple_scan( ptr<ss_decl_seq> seq )
00280 {
00281 return lu_lookup::simple_scan( seq, params_get() );
00282 }
00283
00284 void lu_lookup_in_type::default_action( ptr<ss_type> )
00285 {
00286 lassert2( false, "Trying to run lookup on unknown ss_type." );
00287 }
00288
00289 void lu_lookup_in_type::visit_ss_class( ptr<ss_class> c )
00290 {
00291 ptr<declaration_set_type> result;
00292
00293 result = internal_simple_scan( c->members_get() );
00294 if (!result->empty())
00295 return lookup_result_set( result );
00296
00297 typedef pair<bases_type::const_iterator,bases_type::const_iterator>
00298 iter_pair_type;
00299 typedef list< srp<iter_pair_type> > iter_pair_list_type;
00300
00301 ptr<iter_pair_list_type> st = iter_pair_list_type::create();
00302
00303 st->push_back( iter_pair_type::create( c->bases_get()->begin(), c->bases_get()->end() ) );
00304 while (!st->empty()) {
00305 bases_type::const_iterator & it = st->back()->first;
00306 const bases_type::const_iterator & end_it = st->back()->second;
00307
00308 if (it == end_it) {
00309 st->pop_back();
00310 continue;
00311 }
00312
00313 ptr<ss_class> base_class = (*it)->base_class_get();
00314 ++it;
00315
00316 ptr<declaration_set_type> local_result = internal_simple_scan( base_class->members_get() );
00317 if (local_result->empty()) {
00318
00319 st->push_back( iter_pair_type::create(
00320 base_class->bases_get()->begin(),
00321 base_class->bases_get()->end() ) );
00322 } else
00323 result = unify( result, local_result );
00324 }
00325
00326 lookup_result_set( result );
00327 }
00328
00329 void lu_lookup_in_type::visit_ss_union( ptr<ss_union> u )
00330 {
00331
00332 lookup_result_set( internal_simple_scan( u->members_get() ) );
00333 }
00334
00335 end_package(sem);
00336 end_package(cplus);
00337 end_package(lang);
00338 end_package(lestes);