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/lang/cplus/sem/as_access_specifier_to_ss_access_specifier.g.hh>
00029 #include <lestes/lang/cplus/sem/as_base_specifier_to_ss_base_specifier.g.hh>
00030 #include <lestes/lang/cplus/sem/as_class_key_to_ss_access_specifier.g.hh>
00031 #include <lestes/lang/cplus/sem/as_class_key_to_ss_struct_base.g.hh>
00032 #include <lestes/lang/cplus/sem/as_decl.g.hh>
00033 #include <lestes/lang/cplus/sem/as_id_to_declaration_set.g.hh>
00034 #include <lestes/lang/cplus/sem/as_id_to_ss_decl_name.g.hh>
00035 #include <lestes/lang/cplus/sem/li_class_by_name_in_single_scope.g.hh>
00036 #include <lestes/lang/cplus/sem/sa_class_declaration.g.hh>
00037 #include <lestes/lang/cplus/sem/sa_class_declaration.m.hh>
00038 #include <lestes/lang/cplus/sem/sa_context.g.hh>
00039 #include <lestes/lang/cplus/sem/sa_decl_seq_compound_pair_creator.g.hh>
00040 #include <lestes/lang/cplus/sem/sa_loggers.hh>
00041 #include <lestes/lang/cplus/sem/ss_decl_name.g.hh>
00042 #include <lestes/lang/cplus/sem/ss_declaration.g.hh>
00043 #include <lestes/lang/cplus/sem/ss_declaration_to_ss_decl_seq.g.hh>
00044 #include <lestes/lang/cplus/sem/ss_enums.g.hh>
00045 #include <lestes/lang/cplus/sem/ss_misc.g.hh>
00046 #include <lestes/lang/cplus/sem/ss_statement.g.hh>
00047 #include <lestes/lang/cplus/sem/ss_type.g.hh>
00048 #include <lestes/lang/cplus/sem/ss_type2info.g.hh>
00049 #include <lestes/lang/cplus/syn/manager.hh>
00050 #include <lestes/lang/cplus/syn/token.hh>
00051 #include <lestes/msg/logger.hh>
00052 #include <lestes/msg/logger_util.hh>
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 package(lestes);
00067 package(lang);
00068 package(cplus);
00069 package(sem);
00070
00071
00072
00073
00074
00075
00076
00077
00078 void sa_class_declaration::new_context(ptr< source_location > location, ss_access_specifier::type access_specifier, ptr< ss_decl_seq > scope, ptr< as_name > name)
00079 {
00080 ptr < as_access_specifier > acc_spec;
00081
00082 switch (access_specifier) {
00083 case ss_access_specifier::ACCESS_PUBLIC:
00084 acc_spec = as_access_specifier_public::create(location);
00085 break;
00086 case ss_access_specifier::ACCESS_PRIVATE:
00087 acc_spec = as_access_specifier_private::create(location);
00088 break;
00089 default:
00090 lassert2(false, "Default access specifier for a class has to be either public or private.");
00091
00092 }
00093
00094 ptr < sa_context > new_ctx = sa_context::create(
00095 sa_as_context::create(name, acc_spec),
00096 sa_ss_context::create(scope, access_specifier),
00097 sa_sa_context::create());
00098 sa_context_manager::instance()->push(new_ctx);
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 void sa_class_declaration::process(ptr < as_class_specifier > cs)
00113 {
00114 sa_class_logger << "sa_class_declaration::process begin\n" << msg::eolog;
00115 if (::lestes::lang::cplus::syn::manager::in_disambiguation()) {
00116 sa_class_logger << "nop -- in disambiguation\n" << msg::eolog;
00117 } else {
00118 sa_class_logger << "sa_class_declaration:: location\n" << msg::eolog;
00119 ptr < source_location > location = cs->location_get();
00120
00121
00122
00123
00124
00125 sa_class_logger << "sa_class_declaration:: former declaration?\n" << msg::eolog;
00126
00127 sa_class_logger << "sa_class_declaration:: name\n" << msg::eolog;
00128 ptr < ss_decl_name > decl_name = as_id_to_ss_decl_name::instance()->process(cs->name_get()->identifier_get());;
00129 lassert(decl_name);
00130
00131 sa_class_logger << "sa_class_declaration:: determine scope into which the declaration belongs\n" << msg::eolog;
00132 ptr < ss_decl_seq > seq;
00133 if (cs->name_get()->was_qualified_get()) {
00134 ptr < ::lestes::std::set < srp < ss_declaration > > > qual_declarations =
00135 as_id_to_declaration_set::instance()->process(
00136 cs->name_get()->qualification_get()->identifier_get());
00137 lassert2(qual_declarations->size() == 1,
00138 "Qualification should unambiguously name a single scope declaration");
00139 seq = ss_declaration_to_ss_decl_seq::instance()->process(*qual_declarations->begin());
00140
00141 } else {
00142 seq = sa_context_manager::instance()->current()->ss_get()->scope_get();
00143 }
00144 lassert(seq);
00145
00146
00147 sa_class_logger << "sa_class_declaration:: lookup for potentionaly invisible former declaration\n" << msg::eolog;
00148 ptr < ss_structure_declaration > decl = li_class_by_name_in_single_scope::create()->process(decl_name, seq);
00149
00150 if (decl) {
00151 sa_class_logger << "sa_class_declaration:: process_declared\n" << msg::eolog;
00152 process_declared(cs, decl);
00153 } else {
00154 sa_class_logger << "sa_class_declaration:: process_undeclared\n" << msg::eolog;
00155 process_undeclared(cs);
00156 }
00157 }
00158 sa_class_logger << "sa_class_declaration::process end\n" << msg::eolog;
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 void sa_class_declaration::process_declared(ptr < as_class_specifier > cs, ptr < ss_structure_declaration > class_decl)
00173 {
00174 lassert(!syn::manager::in_disambiguation());
00175
00176 sa_class_declaration_logger << "sa_class_declaration::process_declared begin\n" << msg::eolog;
00177
00178 ptr < source_location > location = cs->location_get();
00179
00180
00181 sa_class_declaration_logger << "visibility\n" << msg::eolog;
00182 ptr < ss_declaration_time > dt
00183 = ss_declaration_time::create(cs->location_get()->order_get());
00184
00185 lassert2(dt->is_before(class_decl->type_get().dncast<ss_struct_base>()->completion_time_get()), "FIXME: report error");
00186 if (!class_decl->visible_since_get()->is_before(dt)) {
00187 sa_class_declaration_logger << "visibility adjusted\n" << msg::eolog;
00188 class_decl->visible_since_set(dt);
00189 }
00190
00191
00192
00193 sa_class_declaration_logger << "determine default access specifier\n" << msg::eolog;
00194 ss_access_specifier::type access_specifier =
00195 as_class_key_to_ss_access_specifier::create()->process(cs->key_get());
00196
00197
00198 sa_class_type_logger << "bases: AS->SS transform\n" << msg::eolog;
00199 ptr < ::lestes::std::list < srp < ss_base_specifier > > > bases =
00200 as_base_specifier_to_ss_base_specifier::create(
00201 access_specifier)->process_list(cs->base_specifiers_get());
00202
00203 sa_class_type_logger << "bases: fill in right place\n" << msg::eolog;
00204 ptr < ss_type > type = class_decl->type_get();
00205
00206 if (type && dynamic_cast<ss_class *>(type.operator->())) {
00207 ptr < ss_class > a_class = type.dncast<ss_class>();
00208 a_class->bases_get()->splice(
00209 a_class->bases_get()->end(), *bases);
00210 }
00211
00212
00213 sa_class_declaration_logger << "context switch\n" << msg::eolog;
00214 new_context(location, access_specifier, class_decl->body_get(), cs->name_get());
00215
00216 sa_class_declaration_logger << "sa_class_declaration::process_declared end\n" << msg::eolog;
00217 }
00218
00219
00220
00221
00222 void sa_class_declaration::process_undeclared(ptr < as_class_specifier > cs)
00223 {
00224 lassert(!syn::manager::in_disambiguation());
00225
00226 sa_class_declaration_logger << "sa_class_declaration::process_undeclared begin\n" << msg::eolog;
00227
00228 sa_class_declaration_logger << "parent declseq get\n" << msg::eolog;
00229 ptr < ss_decl_seq > parent_scope = sa_context_manager::instance()->current()->ss_get()->scope_get();
00230
00231 ptr < ss_structure_declaration > class_decl =
00232 insert_class_forward_into_scope(cs, true, parent_scope);
00233
00234 process_declared(cs, class_decl);
00235
00236 sa_class_declaration_logger << "sa_class_declaration::process_undeclared end\n" << msg::eolog;
00237 }
00238
00239
00240
00241
00242
00243 void sa_class_declaration::process_end(ptr < source_location > location)
00244 {
00245 sa_class_logger << "sa_class_declaration::process_end begin\n" << msg::eolog;
00246 lassert(!syn::manager::in_disambiguation());
00247
00248 sa_class_logger << "mark class as complete\n" << msg::eolog;
00249 sa_context_manager::instance()->current()->ss_get()->scope_get()->declared_by_get()->type_get().dncast<ss_struct_base>()->completion_time_set(ss_declaration_time::create(location->order_get()));
00250 sa_class_logger << "context pop\n" << msg::eolog;
00251 sa_context_manager::instance()->pop();
00252 sa_class_logger << "sa_class_declaration::process_end end\n" << msg::eolog;
00253 }
00254
00255
00256
00257
00258 ptr < ::lestes::lang::cplus::sem::ss_structure_declaration > sa_class_declaration::insert_class_forward_into_scope(ptr < ::lestes::lang::cplus::sem::as_class_specifier > cs, bool visibly, ptr < ::lestes::lang::cplus::sem::ss_decl_seq > parent_scope)
00259 {
00260 lassert(!syn::manager::in_disambiguation());
00261
00262 if (syn::manager::in_disambiguation())
00263 return NULL;
00264
00265 ptr < source_location > location = cs->location_get();
00266
00267 sa_class_logger << "sa_class_declaration:: name\n" << msg::eolog;
00268 ptr < ss_decl_name > decl_name = as_id_to_ss_decl_name::instance()->process(cs->name_get()->identifier_get());;
00269 lassert(decl_name);
00270
00271 sa_class_declaration_logger << "declseq & compound\n" << msg::eolog;
00272 ptr < ::lestes::std::pair < srp < ss_decl_seq >, srp < ss_compound_stmt > > > p =
00273 sa_decl_seq_compound_pair_creator::instance()->process(location,
00274 parent_scope,
00275 parent_scope->compound_stmt_get()
00276 );
00277 lassert(p);
00278
00279 ptr < ss_decl_seq > decl_seq = p->first;
00280 ptr < ss_compound_stmt > stmt = p->second;
00281 lassert(decl_seq && stmt);
00282
00283 sa_class_declaration_logger << "type\n" << msg::eolog;
00284 ptr < ss_struct_base > type =
00285 as_class_key_to_ss_struct_base::create(
00286 decl_seq,
00287 ::lestes::std::list < srp < ss_base_specifier > >::create()
00288 )->process(cs->key_get());
00289
00290 sa_class_declaration_logger << "proper\n" << msg::eolog;
00291 ptr < ss_structure_declaration > class_decl = ss_structure_declaration::create(
00292 location,
00293 visibly
00294 ? ss_declaration_time::create(location->order_get())
00295 : ss_declaration_time::infinity(),
00296 ss_declaration_time::create(location->order_get()),
00297 decl_name,
00298 parent_scope,
00299 type,
00300
00301 ss_linkage::create("C++",ss_linkage::LINKAGE_EXTERNAL),
00302 sa_context_manager::instance()->current()->ss_get()->access_specifier_get(),
00303 ss_storage_class::ST_NONE,
00304 ::lestes::std::set< srp< ss_struct_base > >::create(),
00305 decl_seq
00306 );
00307
00308 sa_class_declaration_logger << "injected\n" << msg::eolog;
00309 ptr < ss_injected_class_declaration > class_decl_alias = ss_injected_class_declaration::create(
00310 location,
00311 ss_declaration_time::create(location->order_get()),
00312 ss_declaration_time::create(location->order_get()),
00313 decl_name,
00314 decl_seq,
00315 type,
00316
00317 class_decl->linkage_get(),
00318 ss_access_specifier::ACCESS_PUBLIC,
00319 ss_storage_class::ST_NONE,
00320 class_decl
00321 );
00322
00323 sa_class_declaration_logger << "fixup circular structures\n" << msg::eolog;
00324
00325 type->decl_set(class_decl);
00326 decl_seq->declared_by_set(class_decl);
00327 decl_seq->contents_get()->push_back(class_decl_alias);
00328 parent_scope->contents_get()->push_back(class_decl);
00329
00330 return class_decl;
00331
00332 }
00333
00334
00335
00336
00337
00338
00339 void sa_class_declaration::process_forward_declaration(ptr < as_class_specifier > cs)
00340 {
00341 if (!syn::manager::in_disambiguation()) {
00342 ptr<ss_decl_seq> ds =
00343 sa_context_manager::instance()->current()->ss_get()->scope_get();
00344 insert_class_forward_into_scope(cs, true, ds);
00345 }
00346 }
00347
00348 end_package(sem);
00349 end_package(cplus);
00350 end_package(lang);
00351 end_package(lestes);
00352