sa_simple_declaration.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 Simple declaration analysis.
00030 
00031   Analysis of simple declaration and its conversion to ss_declaration.
00032 */
00033 #include <lestes/common.hh>
00034 #include <lestes/lang/cplus/sem/sa_simple_declaration.g.hh>
00035 #include <lestes/lang/cplus/sem/sa_simple_declaration.m.hh>
00036 #include <lestes/lang/cplus/sem/declaration_broadcasting.hh>
00037 #include <lestes/lang/cplus/sem/as_decl.g.hh>
00038 #include <lestes/lang/cplus/sem/as_declarator_op2op_func.g.hh>
00039 #include <lestes/lang/cplus/sem/as_id_to_ss_decl_name.g.hh>
00040 #include <lestes/lang/cplus/sem/as_id_to_declaration_set.g.hh>
00041 #include <lestes/lang/cplus/sem/as_other.g.hh>
00042 #include <lestes/lang/cplus/sem/sa_context.g.hh>
00043 #include <lestes/lang/cplus/sem/sa_decl_seq_compound_pair_creator.g.hh>
00044 #include <lestes/lang/cplus/sem/sa_declaration_specifiers.g.hh>
00045 #include <lestes/lang/cplus/sem/sa_declaration_specifier_list.g.hh>
00046 #include <lestes/lang/cplus/sem/sa_declarator_type.g.hh>
00047 #include <lestes/lang/cplus/sem/sa_param_declaration.g.hh>
00048 #include <lestes/lang/cplus/sem/ss_misc.g.hh>
00049 #include <lestes/lang/cplus/sem/ss_declaration.g.hh>
00050 #include <lestes/lang/cplus/sem/ss_declaration2ss_typedef_definition.g.hh>
00051 #include <lestes/lang/cplus/sem/ss_declaration2ss_namespace_definition.g.hh>
00052 #include <lestes/lang/cplus/sem/ss_declaration2ss_structure_declaration.g.hh>
00053 #include <lestes/lang/cplus/sem/ss_declaration2ss_object_declaration.g.hh>
00054 #include <lestes/lang/cplus/sem/ss_declaration2ss_function_declaration.g.hh>
00055 #include <lestes/lang/cplus/sem/ss_statement.g.hh>
00056 #include <lestes/lang/cplus/sem/ss_type.g.hh>
00057 #include <lestes/lang/cplus/sem/ss_decl_name.g.hh>
00058 #include <lestes/lang/cplus/sem/li_func_by_name_in_single_scope.g.hh>
00059 #include <lestes/lang/cplus/sem/li_by_name_in_single_scope.g.hh>
00060 #include <lestes/lang/cplus/sem/li_non_secu_by_name_in_single_scope.g.hh>
00061 #include <lestes/lang/cplus/sem/or_or.g.hh>
00062 #include <lestes/lang/cplus/syn/manager.hh>
00063 #include <lestes/lang/cplus/syn/token.hh>
00064 #include <lestes/lang/cplus/sem/sa_loggers.hh>
00065 #include <lestes/msg/logger.hh>
00066 #include <lestes/msg/logger_util.hh>
00067 
00068 #include <algorithm>
00069 #include <iterator>
00070 #include <cstdlib>
00071 
00072 package(lestes);
00073 package(lang);
00074 package(cplus);
00075 package(sem);
00076 
00077 /*!
00078   Saves declaration specifiers to the context.
00079   \pre specifiers != NULL
00080   \param specifiers The declaration specifiers.
00081 */
00082 void sa_simple_declaration::save_declaration_specifiers(ptr<as_declaration_specifier_seq> specifiers)
00083 {
00084         sa_simple_declaration_logger << "sa_simple_declaration::save_declaration_specifiers()\n" << msg::eolog;
00085         lassert(specifiers);
00086         
00087         if (::lestes::lang::cplus::syn::manager::in_disambiguation()) {
00088                 sa_simple_declaration_logger << "nop -- in disambiguation\n" << msg::eolog;
00089         } else {
00090                 sa_simple_declaration_logger << "saving specifiers\n" << msg::eolog;
00091                 sa_context_manager::instance()->current()->as_get()->declaration_specifier_seq_set(specifiers);
00092         }
00093 
00094         sa_simple_declaration_logger << "sa_simple_declaration::save_declaration_specifiers() end\n" << msg::eolog;
00095 }
00096 
00097 /*!
00098   Saves declaration specifiers to the context.
00099   \pre specifiers != NULL
00100   \param specifiers The declaration specifiers.
00101 */
00102 void sa_simple_declaration::save_type_specifiers(ptr<as_type_specifier_seq> specifiers)
00103 {
00104         sa_simple_declaration_logger << "sa_simple_declaration::save_type_specifiers()\n" << msg::eolog;
00105         lassert(specifiers);
00106         
00107         if (::lestes::lang::cplus::syn::manager::in_disambiguation()) {
00108                 sa_simple_declaration_logger << "nop -- in disambiguation\n" << msg::eolog;
00109         } else {
00110                 sa_simple_declaration_logger << "saving specifiers\n" << msg::eolog;
00111                 ptr<as_declaration_specifier_seq> asdss =
00112                         as_declaration_specifier_seq::create(
00113                                         specifiers->location_get(),
00114                                         list< srp<as_declaration_specifier> >::create());
00115                 ::std::copy(specifiers->l_get()->begin(),specifiers->l_get()->end(),::std::back_inserter(*(asdss->l_get())));
00116                 sa_context_manager::instance()->current()->as_get()->declaration_specifier_seq_set(asdss);
00117         }
00118 
00119         sa_simple_declaration_logger << "sa_simple_declaration::save_type_specifiers() end\n" << msg::eolog;
00120 }
00121 
00122 //! Type of list of as_declarator_op elements.
00123 typedef list< srp<as_declarator_op> > as_declarator_op_list_type;
00124 
00125 //! Type of set of ss_declaration elements.
00126 typedef ::lestes::std::set< srp<ss_declaration> > ss_declaration_set_type;
00127 
00128 /*!
00129   Processes declarator and either creates a declaration, or modifies a previously
00130   established declaration of the same entity.
00131   \pre declarator != NULL
00132   \param declarator  The declarator to process.
00133 */
00134 void sa_simple_declaration::process(ptr<as_declarator> declarator)
00135 {
00136         sa_simple_declaration_logger << "sa_simple_declaration::process()\n" << msg::eolog;
00137 
00138         if (::lestes::lang::cplus::syn::manager::in_disambiguation()) {
00139                 sa_simple_declaration_logger << "nop -- in disambiguation\n" << msg::eolog;
00140                 sa_simple_declaration_logger << "sa_simple_declaration::process() end\n" << msg::eolog;
00141                 return;
00142         }
00143         
00144         lassert2(declarator->name_get(),"Name not filled in declarator");
00145 
00146         ptr<sa_context> ctx = sa_context_manager::instance()->current();
00147         
00148         sa_simple_declaration_logger << "processing declaration specifiers\n" << msg::eolog;
00149 
00150         // process declaration specifiers
00151         // TODO like this, or processed in sa_get() ???
00152 
00153         // TODO do not create specifiers, just reference them once ?? better  not
00154         ptr<as_declaration_specifier_seq> adss = ctx->as_get()->declaration_specifier_seq_get();
00155         ptr<as_declaration_specifier_list_type> adsl = adss->l_get();
00156         
00157         ptr<sa_declaration_specifier_list> sdsl = sa_declaration_specifier_list::create();
00158         ptr<sa_declaration_specifiers> sads = sdsl->process(adss->location_get(),adsl);
00159         
00160         if (sads->storage_class_get() == ss_storage_class::ST_TYPEDEF) {
00161                 sa_simple_declaration_logger << "got typedef\n" << msg::eolog;
00162                 // handle typedef
00163                 process_typedef(ctx,sads,declarator);
00164         } else {
00165                 sa_simple_declaration_logger << "distinguish function from object\n" << msg::eolog;
00166 
00167                 ptr<as_declarator_op_list_type> adol = declarator->declarator_ops_get();
00168         
00169                 ptr<as_declarator_op_func> asdof;
00170                 
00171                 // check whether the first declarator op is func
00172                 if (!adol->empty())
00173                         asdof = as_declarator_op2op_func::instance()->process(adol->front());
00174                 
00175                 if (asdof) {
00176                         sa_simple_declaration_logger << "got function declaration\n" << msg::eolog;
00177                 
00178                         // TODO pt process_function_declaration(ctx,sads,declarator);
00179                         // also get the necessary info for parameter declarations if toplevel is function
00180                         process_function_declaration(ctx,asdof,sads,declarator);
00181 
00182                 } else {
00183                         sa_simple_declaration_logger << "got object declaration\n" << msg::eolog;
00184                         
00185                         process_object_declaration(ctx,sads,declarator);
00186                 }
00187         }
00188         
00189         sa_simple_declaration_logger << "sa_simple_declaration::process() end\n" << msg::eolog;
00190 }
00191 
00192 /*!
00193   Processes function declaration and either creates a declaration, or modifies a previously
00194   established declaration of the same function.
00195   \pre ctx != NULL
00196   \pre op_func != NULL
00197   \pre specifiers != NULL
00198   \pre declarator != NULL
00199   
00200   \param ctx  The context containing the scope.
00201   \param op_func  The function declarator operator, containing the parameters.
00202   \param specifiers  The declaration specifiers of the declaration.
00203   \param declarator  The function declarator to process.
00204 */
00205 void sa_simple_declaration::process_function_declaration(ptr<sa_context> ctx, ptr<as_declarator_op_func> op_func,
00206                 ptr<sa_declaration_specifiers> specifiers, ptr<as_declarator> declarator)
00207 {
00208         sa_simple_declaration_logger << "sa_simple_declaration::process_function_declaration()\n" << msg::eolog;
00209 
00210         lassert(ctx);
00211         lassert(op_func);
00212         lassert(specifiers);
00213         lassert(declarator);
00214 
00215         sa_simple_declaration_logger << "checking declaration specifier flags\n" << msg::eolog;
00216 
00217         // TODO pt distinguish whether we are in class scope declaring, defining
00218         // with implicit inline, or whehter defining method in namespace scope
00219         // or declaring function in ns/fun scope
00220         // or defining function in ns scope (parser won't allow defining fun in fun scope)
00221         // TODO pt check if in class so that we can use v/f/e/i flags
00222         
00223         ptr<ss_decl_seq> ctx_scope = ctx->ss_get()->scope_get();
00224         ptr<ss_declaration> ctx_decl = ctx_scope->declared_by_get();
00225 
00226         ptr<ss_structure_declaration> sssd = ss_declaration2ss_structure_declaration::instance()->process(ctx_decl);
00227         
00228         if (sssd) {
00229                 sa_simple_declaration_logger << "declaration is in class\n" << msg::eolog;
00230                 if (specifiers->friend_flag_get()) {
00231                         sa_simple_declaration_logger << "declaration is a friend function\n" << msg::eolog;
00232 
00233                         lassert2(false,"Friend functions not implemented.");
00234                         // TODO pt
00235                         //process_friend_function_declaration(ctx,specifiers,declarator);
00236 
00237                 } else {
00238                         sa_simple_declaration_logger << "declaration is a method\n" << msg::eolog;
00239 
00240                         report << methods_not_implemented << declarator->location_get();
00241                         return;
00242                         // was:
00243                         lassert2(false,"Method declarations not implemented.");
00244                         // TODO pt
00245                         // process_method_declaration(ctx,specifiers,declarator);
00246                 }
00247         } else {
00248                 sa_simple_declaration_logger << "declaration is out of class\n" << msg::eolog;
00249                 if (specifiers->virtual_flag_get() || specifiers->friend_flag_get() || specifiers->explicit_flag_get() ||
00250                          specifiers->inline_flag_get()) {
00251                         sa_simple_declaration_logger << "got some invalid flags\n" << msg::eolog;
00252                         // TODO pt distinguish which flag to give more accurate error report
00253                         // error: invalid specifier in function declaration
00254                         report << invalid_specifier_function << declarator->location_get();
00255                 }
00256 
00257                 // TODO pt check storage and distinguish extern from normal so that type processor can
00258                 // be called in the proper regime
00259 
00260                 // for now, just do the definition
00261                 // TODO how will i know extern f() {} ????
00262 
00263                 sa_simple_declaration_logger << "converting the name\n" << msg::eolog;
00264 
00265                 ptr<as_name> name = declarator->name_get();
00266                 // get the ss equivalent of the name
00267                 ptr<ss_decl_name> decl_name = as_id_to_ss_decl_name::instance()->process(name->identifier_get());
00268 
00269                 /*
00270                  analyse the RETURN type of the function (that is easy, just omit the first declspec)
00271                  
00272                  now pass the return type to the second analyser, also pass the op_func
00273                  to get the ss_type of the whole and list of the sa_declaration_specifiers
00274                  
00275                  the third analyser should take care of all parameter declarations
00276                  pass op_func and the sa_declaration_specifiers list
00277                  perhaps including the creation of the special parameter scope, which
00278                  alas! has to be returned, so perhaps create it outside, hell that makes
00279                  alot of code in here, perhaps some method would be enough
00280                  
00281                  
00282                  */
00283 
00284 #if 0
00285                 sa_simple_declaration_logger << "extracting the ss_type from declarator\n" << msg::eolog;
00286                 
00287                 // extract the function return type
00288                 // TODO pt change for visit-return- as well as sa_declarator_type TODO
00289                 ptr<sa_declarator_return_type> sadrt = sa_declarator_return_type::create();
00290                 ptr<ss_type> return_type = sadrt->process(specifiers->type_get(),declarator);
00291 
00292                 // extract the function type and parameter specifiers
00293                 ptr<sa_function_type> saft = sa_function_type::create();
00294                 saft->process(return_type,op_func);
00295                 ptr< list< srp<sa_declaration_specifiers> > > param_specifiers =
00296                         saft->param_declaration_specifiers_get();
00297                 ptr<ss_type> type = saft->type_get();
00298 #endif
00299                 // TODO ordinary type for now, with duplicate ds processing
00300                 // TODO we need ss_function, solve this together
00301                 ptr<ss_function> type =
00302                         (sa_declarator_type::create()->process(specifiers->type_get(),declarator)).dncast<ss_function>();
00303 
00304                 ptr<ss_declaration> declaration;
00305 
00306                 // TODO lookup the function and check if it exists
00307                 //typedef set< srp<ss_function_declaration> > ss_function_declaration_set_type;
00308                 typedef set< srp<ss_declaration> > ss_declaration_set_type;
00309                 // TODO pt li as singleton
00310                 ptr<ss_declaration_set_type> ssds = li_non_secu_by_name_in_single_scope::create()->process(decl_name,ctx_scope);
00311 
00312                 if (!ssds->empty())
00313                         sa_simple_declaration_logger << "found some declarations with the same name\n" << msg::eolog;
00314 
00315                 bool error = false;
00316                 
00317                 ptr<ss_function_declaration> found_decl;
00318 
00319                 for (ss_declaration_set_type::iterator it = ssds->begin(), end = ssds->end();
00320                                 it != end; ++it) {
00321                         ptr<ss_function_declaration> ssfd =
00322                                 ss_declaration2ss_function_declaration::instance()->process(*it);
00323                         
00324                         if (ssfd) {
00325                                 // TODO pt
00326                                 ptr<ss_function> ssft = (ssfd->type_get()).dncast<ss_function>();
00327 
00328                                 if (ssft->equal_signature(type)) {
00329                                         sa_simple_declaration_logger << "found function with the same signature\n" << msg::eolog;
00330 
00331                                         lassert2(!found_decl,"Two function declarations with the same signature found.");
00332 
00333                                         if (ssft->returns_get() != type->returns_get()) {
00334                                                 sa_simple_declaration_logger << "error: the return types are different\n" << msg::eolog;
00335                                                 report << different_return_types << declarator->location_get();
00336                                                 report << previous_declaration << ssfd->location_get();
00337                                         /*      sa_simple_declaration_logger <<
00338                                                         "sa_simple_declaration::process_function_declaration() end\n" << msg::eolog;
00339                                          */
00340                                                 error = true;
00341                                                 break;
00342                                         }
00343                                         sa_simple_declaration_logger << "the return types match\n" << msg::eolog;
00344                                         found_decl = ssfd;
00345 
00346                                         // wait for different redeclarations
00347                                 }
00348                         } else {
00349                                 report << redeclaration_different << declarator->location_get();
00350                                 report << previous_declaration << (*it)->location_get();
00351                                 error = true;
00352                                 break;
00353                         }
00354                 }
00355 
00356                 if (error) {
00357          exit(1);
00358                 } if (found_decl) {
00359                         sa_simple_declaration_logger << "processing the found function declaration\n" << msg::eolog;
00360          declaration = found_decl;
00361 
00362                         // check the defaults set before merging with the current ones
00363                         // how ? create the params again and compare ???
00364 
00365                         /*
00366                                 
00367                         ptr<source_location> loc = declarator->location_get();
00368                         // create scope for parameters
00369                         ptr<ss_decl_seq> param_scope = 
00370                                 sa_decl_seq_compound_pair_creator::instance()->process(loc,
00371                                                 current_scope,current_scope->compound_stmt_get())->first;
00372 
00373                         typedef list< srp<as_param_declaration> > as_param_declaration_list;
00374                         ptr<as_param_declaration_list> aspdl = op_func->parameters_get()->parameters_get();
00375 
00376                         sa_simple_declaration_logger << "creating parameter declarations\n" << msg::eolog;
00377                         
00378                         // declare the parameters
00379                         ptr<sa_param_declaration> sapd = sa_param_declaration::create(param_scope);
00380 
00381                         for (as_param_declaration_list::iterator it = aspdl->begin(), end = aspdl->end();
00382                                         it != end; ++it) {
00383                                 sapd->process(*it);
00384                         }
00385 
00386                         */
00387                         
00388                         sa_simple_declaration_logger << "merging parameter declarations\n" << msg::eolog;
00389 
00390                         // TODO pt merge
00391 
00392                 } else {
00393                         sa_simple_declaration_logger << "adding new function declaration\n" << msg::eolog;
00394 
00395 
00396                         // TODO pt what about those funny little thingies in op_func
00397                         // like const, volatile for methods, where are these checked?
00398                         // at least that they are not present ^_^
00399 
00400                         // TODO this might be different
00401                         ptr<ss_decl_seq> current_scope = ctx->ss_get()->scope_get();
00402                         
00403                         ptr<source_location> loc = declarator->location_get();
00404                         // create scope for parameters
00405                         ptr<ss_decl_seq> param_scope = 
00406                                 sa_decl_seq_compound_pair_creator::instance()->process(loc,
00407                                                 current_scope,current_scope->compound_stmt_get())->first;
00408 
00409                         typedef list< srp<as_param_declaration> > as_param_declaration_list;
00410                         ptr<as_param_declaration_list> aspdl = op_func->parameters_get()->parameters_get();
00411 
00412                         sa_simple_declaration_logger << "creating parameter declarations\n" << msg::eolog;
00413                         
00414                         // declare the parameters
00415                         ptr<sa_param_declaration> sapd = sa_param_declaration::create(param_scope);
00416 
00417                         for (as_param_declaration_list::iterator it = aspdl->begin(), end = aspdl->end();
00418                                         it != end; ++it) {
00419                                 sapd->process(*it);
00420                         }
00421 
00422 #if 0
00423                         for (list< srp< sa_declaration_specifiers > >::iterator it = param_specifiers->begin(),
00424                                         end = param_specifiers->end(); it != end; ++it) {
00425                                 sapd->process(*it);
00426                         }
00427 #endif
00428                         
00429                         ptr<ss_declaration_time> dt = ss_declaration_time::create(loc->order_get());
00430 
00431                         sa_simple_declaration_logger << "creating the function declaration\n" << msg::eolog;
00432 
00433                         // declare the function
00434                    declaration = ss_function_declaration::create(
00435                                 loc, // location 
00436                                 dt, // visible time
00437                                 dt, // declaration time
00438                                 decl_name, // declaration name
00439                                 current_scope, // contained in
00440                                 type, // type
00441                                 // TODO pt fill
00442                                 ss_linkage::create("C++",ss_linkage::LINKAGE_EXTERNAL), // linkage
00443                                 param_scope, // parameters
00444                                 // TODO pt body???
00445                                 NULL // body
00446                                 );
00447                 
00448                         // fix the parameter scope
00449                         param_scope->declared_by_set(declaration);
00450 
00451                         // param ds: jeho parent je current scope
00452 
00453                         sa_simple_declaration_logger << "adding the declaration\n" << msg::eolog;
00454 
00455                         current_scope->contents_get()->push_back(declaration);
00456 
00457                 }
00458 
00459       sa_simple_declaration_logger << "announce new declaration\n" << msg::eolog;
00460       // TMA: make the declaration known to egg
00461       declaration_finished->broadcast(declaration);
00462         }
00463         
00464         sa_simple_declaration_logger << "sa_simple_declaration::process_function_declaration() end\n" << msg::eolog;
00465 }
00466 
00467 void process_friend_function_declaration(ptr<sa_context> ctx, ptr<sa_declaration_specifiers> specifiers,
00468         ptr<as_declarator> declarator)
00469 {
00470         lassert(ctx && specifiers && declarator);
00471         lassert(false);
00472 }
00473 
00474 /*!
00475   Processes object declaration. If the name exists and refers to an object of the same type,
00476   it is checked, whether a declaration is also a definition and appropriate structures are updated.
00477   Multiple definition renders the program ill-formed. If the name refers to another entity,
00478   the program is ill-formed. If the name does not exists, a new declaration is added to the current scope,
00479   or another enclosing scope according to its storage class and the kind of the current scope.
00480   \pre ctx != NULL
00481   \pre specifiers != NULL
00482   \pre declarator != NULL
00483   \param ctx  The context of the analyser.
00484   \param specifiers  The processed declaration specifiers of the object.
00485   \param declarator  The declarator of the object.
00486 */
00487 void sa_simple_declaration::process_object_declaration(ptr<sa_context> ctx, ptr<sa_declaration_specifiers> specifiers,
00488                 ptr<as_declarator> declarator)
00489 {
00490         sa_simple_declaration_logger << "sa_simple_declaration::process_object_declaration()\n" << msg::eolog;
00491 
00492         lassert(ctx);
00493         lassert(specifiers);
00494         lassert(declarator);
00495 
00496         sa_simple_declaration_logger << "checking declaration specifier flags\n" << msg::eolog;
00497         
00498         if (specifiers->virtual_flag_get() || specifiers->friend_flag_get() || specifiers->explicit_flag_get() ||
00499                  specifiers->inline_flag_get()) {
00500                 sa_simple_declaration_logger << "got some invalid flags\n" << msg::eolog;
00501                 // TODO pt distinguish which flag to give more accurate error report
00502                 // error: invalid specifier in object declaration
00503                 report << invalid_specifier_object << declarator->location_get();
00504         }
00505         
00506         sa_simple_declaration_logger << "extracting the ss_type from declarator\n" << msg::eolog;
00507         
00508         // extract the plain type
00509         ptr<sa_declarator_type> sdt = sa_declarator_type::create();
00510         ptr<ss_type> type = sdt->process(specifiers->type_get(),declarator);
00511 
00512         sa_simple_declaration_logger << "converting the name\n" << msg::eolog;
00513 
00514         ptr<as_name> name = declarator->name_get();
00515         // get the ss equivalent of the name
00516         ptr<ss_decl_name> decl_name = as_id_to_ss_decl_name::instance()->process(name->identifier_get());
00517 
00518         // TODO pt different
00519         ptr<ss_decl_seq> current_scope = ctx->ss_get()->scope_get();
00520         bool ns = ss_declaration2ss_namespace_definition::instance()->process(current_scope->declared_by_get());
00521         bool cs = ss_declaration2ss_structure_declaration::instance()->process(current_scope->declared_by_get());
00522    
00523         ss_storage_class::type storage_class = specifiers->storage_class_get();
00524 
00525         sa_simple_declaration_logger << "looking up the name\n" << msg::eolog;
00526 
00527         ptr<ss_declaration_set_type> decls = li_non_secu_by_name_in_single_scope::create()->process(decl_name,current_scope);
00528    ptr<ss_declaration> declaration;
00529 
00530         ss_declaration_set_type::iterator it = decls->begin();
00531         if (it != decls->end()) {
00532                 sa_simple_declaration_logger << "found some declarations\n" << msg::eolog;
00533           
00534            declaration = *it;
00535 
00536                 // TODO pt bugbug
00537       /*
00538                 sa_simple_declaration_logger << "found " << 
00539                         declaration->name_get().dncast<ss_ordinary_name>()->name_get() << "\n" << msg::eolog;
00540          */
00541                 
00542                 // check that the name refers to an object
00543                 ptr<ss_object_declaration> ssod = ss_declaration2ss_object_declaration::instance()->process(declaration);
00544 
00545                 if (ssod) {
00546                         if (ssod->type_get() != type) {
00547                                 sa_simple_declaration_logger << "error: the type does not match\n" << msg::eolog;
00548                                 report << conflicting_types << declarator->location_get();
00549                                 report << previous_declaration << (*it)->location_get();
00550                         }
00551 
00552                         sa_simple_declaration_logger << "analysing found storage specifiers\n" << msg::eolog;
00553          
00554          ss_storage_class::type old_storage = ssod->storage_class_get();
00555 
00556                         // analyse storage and ban 2xdefinition
00557                          
00558          if (cs) {
00559             report << field_redefinition << declarator->location_get();
00560             report << previous_declaration << declaration->location_get();
00561             // TODO pt
00562             exit(1);
00563          } if (ns) {
00564             switch (storage_class) {
00565                case ss_storage_class::ST_AUTO:
00566                case ss_storage_class::ST_REGISTER:
00567                case ss_storage_class::ST_MUTABLE:
00568                   // report error: invalid storage specifiers
00569                   report << invalid_storage_specifier << declarator->location_get(); 
00570                   storage_class = ss_storage_class::ST_NONE;
00571                   // fall through
00572                case ss_storage_class::ST_NONE:
00573                   switch (old_storage) {
00574                      case ss_storage_class::ST_NONE:
00575                      case ss_storage_class::ST_STATIC:
00576                      case ss_storage_class::ST_DEFINED:
00577                         report << redefinition << declarator->location_get(); 
00578                         report << previous_declaration << declaration->location_get();
00579                         storage_class = old_storage;
00580                         break;
00581                      case ss_storage_class::ST_EXTERN:
00582                         storage_class = ss_storage_class::ST_DEFINED;
00583                         break;
00584                      default:
00585                         lassert2(false,"You should never get here");
00586                   }
00587                   break;
00588                case ss_storage_class::ST_STATIC:
00589                   switch (old_storage) {
00590                      case ss_storage_class::ST_EXTERN:
00591                      case ss_storage_class::ST_DEFINED:
00592                         report << static_and_extern << declarator->location_get(); 
00593                         storage_class = old_storage;
00594                         break;
00595                      case ss_storage_class::ST_NONE:
00596                      case ss_storage_class::ST_STATIC:
00597                         report << redefinition << declarator->location_get(); 
00598                         report << previous_declaration << declaration->location_get();
00599                         storage_class = old_storage;
00600                         break;
00601                      default:
00602                         lassert2(false,"You should never get here");
00603                   }
00604                   break;
00605                case ss_storage_class::ST_EXTERN:
00606                   switch (old_storage) {
00607                      case ss_storage_class::ST_EXTERN:
00608                      case ss_storage_class::ST_DEFINED:
00609                         storage_class = old_storage;
00610                         break;
00611                      case ss_storage_class::ST_NONE:
00612                         storage_class = ss_storage_class::ST_DEFINED;
00613                         break;
00614                      case ss_storage_class::ST_STATIC:
00615                         report << static_and_extern << declarator->location_get(); 
00616                         storage_class = old_storage;
00617                         break;
00618                      default:
00619                         lassert2(false,"You should never get here");
00620                   }
00621                   break;
00622                case ss_storage_class::ST_DEFINED:
00623                   switch (old_storage) {
00624                      case ss_storage_class::ST_EXTERN:
00625                         storage_class = old_storage;
00626                         break;
00627                      case ss_storage_class::ST_DEFINED:
00628                      case ss_storage_class::ST_NONE:
00629                         report << redefinition << declarator->location_get(); 
00630                         report << previous_declaration << declaration->location_get();
00631                         storage_class = old_storage;
00632                         break;
00633                      case ss_storage_class::ST_STATIC:
00634                         report << static_and_extern << declarator->location_get(); 
00635                         storage_class = old_storage;
00636                         break;
00637                      default:
00638                         lassert2(false,"You should never get here");
00639                   }
00640                   break;
00641                case ss_storage_class::ST_TYPEDEF:
00642                default:
00643                   lassert2(false,"You should never get here");
00644             }
00645          } else {
00646             switch (old_storage) {
00647                case ss_storage_class::ST_NONE:
00648                case ss_storage_class::ST_AUTO:
00649                case ss_storage_class::ST_REGISTER:
00650                   report << redefinition << declarator->location_get(); 
00651                   report << previous_declaration << declaration->location_get();
00652                   storage_class = old_storage;
00653                   break;
00654                case ss_storage_class::ST_EXTERN:
00655                   lassert2(false,"Extern in function not supported.");
00656                   break;
00657                case ss_storage_class::ST_STATIC:
00658                   lassert2(false,"Static in function not supported.");
00659                   break;
00660                case ss_storage_class::ST_MUTABLE:
00661                   // report error: invalid storage specifiers
00662                   report << invalid_storage_specifier << declarator->location_get(); 
00663                   storage_class = ss_storage_class::ST_NONE;
00664                   break;
00665                case ss_storage_class::ST_TYPEDEF:
00666                default:
00667                   lassert2(false,"You should never get here");
00668             }
00669          }
00670 
00671          // set the new storage class
00672          ssod->storage_class_set(storage_class);
00673                         
00674                 } else {
00675                         sa_simple_declaration_logger << "error: the found declaration does not declare object\n" << msg::eolog;
00676                         report << redeclaration_different << declarator->location_get();
00677                         report << previous_declaration << (*it)->location_get();
00678                 }
00679 
00680         } else {
00681 
00682                 // check the storage class
00683                 
00684       if (ns) {
00685          switch (storage_class) {
00686             case ss_storage_class::ST_NONE:
00687             case ss_storage_class::ST_STATIC:
00688             case ss_storage_class::ST_EXTERN:
00689                break;
00690             case ss_storage_class::ST_MUTABLE:
00691             case ss_storage_class::ST_AUTO:
00692             case ss_storage_class::ST_REGISTER:
00693                // report error: invalid storage specifiers
00694                report << invalid_storage_specifier << declarator->location_get(); 
00695                storage_class = ss_storage_class::ST_NONE;
00696                break;
00697             case ss_storage_class::ST_TYPEDEF:
00698             default:
00699                lassert2(false,"You should never get here");
00700          }
00701       } else if (cs) {
00702          switch (storage_class) {
00703             case ss_storage_class::ST_AUTO:
00704             case ss_storage_class::ST_REGISTER:
00705             case ss_storage_class::ST_EXTERN:
00706                // report error: invalid storage specifiers
00707                report << field_storage_specifier << declarator->location_get(); 
00708                storage_class = ss_storage_class::ST_NONE;
00709                break;
00710             case ss_storage_class::ST_NONE:
00711             case ss_storage_class::ST_STATIC:
00712             case ss_storage_class::ST_MUTABLE:
00713                break;
00714             case ss_storage_class::ST_TYPEDEF:
00715             default:
00716                lassert2(false,"You should never get here");
00717          }
00718       } else {
00719          switch (storage_class) {
00720             case ss_storage_class::ST_NONE:
00721             case ss_storage_class::ST_AUTO:
00722             case ss_storage_class::ST_REGISTER:
00723                storage_class = ss_storage_class::ST_NONE;
00724                break;
00725                case ss_storage_class::ST_EXTERN:
00726                   lassert2(false,"Extern in function not supported.");
00727                   break;
00728                case ss_storage_class::ST_STATIC:
00729                   lassert2(false,"Static in function not supported.");
00730                   break;
00731             case ss_storage_class::ST_MUTABLE:
00732                // report error: invalid storage specifiers
00733                report << invalid_storage_specifier << declarator->location_get(); 
00734                storage_class = ss_storage_class::ST_NONE;
00735                break;
00736             case ss_storage_class::ST_TYPEDEF:
00737             default:
00738                lassert2(false,"You should never get here");
00739          }
00740       }
00741                 
00742                 ptr<source_location> loc = declarator->location_get();
00743                 ptr<ss_declaration_time> dt = ss_declaration_time::create(loc->order_get());
00744 
00745                 sa_simple_declaration_logger << "creating the object declaration\n" << msg::eolog;
00746 
00747                 // create the object declaration
00748                 declaration = ss_object_declaration::create(
00749                         loc, // location
00750                         dt, // visible since
00751                         dt, // declaration time
00752                         decl_name, // declaration name
00753                         current_scope, // contained in
00754                         type, // ss type
00755                         // TODO pt from context via visitor
00756                         ss_linkage::create("C++",ss_linkage::LINKAGE_NO), // linkage
00757                         ctx->ss_get()->access_specifier_get(),
00758                         storage_class, // storage class
00759                         ss_declaration_time::infinity(), // initialized since
00760                         NULL // initializer
00761                         );
00762 
00763                 // TODO pt choose scope to add the declaration to
00764 
00765                 sa_simple_declaration_logger << "adding the declaration to current scope\n" << msg::eolog;
00766 
00767                 // add the declaration into the current scope
00768                 current_scope->contents_get()->push_back(declaration);
00769 
00770         }
00771 
00772    sa_simple_declaration_logger << "announce new declaration\n" << msg::eolog;
00773    // TMA: make the declaration known to egg
00774    declaration_finished->broadcast(declaration);
00775 
00776         sa_simple_declaration_logger << "sa_simple_declaration::process_object_declaration() end\n" << msg::eolog;
00777 }
00778 
00779 /*!
00780   Processes typedef definition. If the name exists and refers to a type, a check is done
00781   to ensure that the original type and the new type are the same. If the name refers to
00782   a non-type, the program is ill-formed. If the name does not exists, the newly defined
00783   type is added to the current scope.
00784   \pre ctx != NULL
00785   \pre specifiers != NULL
00786   \pre declarator != NULL
00787   \param ctx  The context of the analyser.
00788   \param specifiers  The processed declaration specifiers of the typedef.
00789   \param declarator  The declarator of the typedef.
00790 */
00791 void sa_simple_declaration::process_typedef(ptr<sa_context> ctx, ptr<sa_declaration_specifiers> specifiers,
00792                 ptr<as_declarator> declarator)
00793 {
00794         sa_simple_declaration_logger << "sa_simple_declaration::process_typedef()\n" << msg::eolog;
00795 
00796         lassert(ctx);
00797         lassert(specifiers);
00798         lassert(declarator);
00799 
00800         sa_simple_declaration_logger << "checking declaration specifier flags\n" << msg::eolog;
00801         
00802         if (specifiers->virtual_flag_get() || specifiers->friend_flag_get() || specifiers->explicit_flag_get() ||
00803                  specifiers->inline_flag_get()) {
00804                 sa_simple_declaration_logger << "got some invalid flags\n" << msg::eolog;
00805                 // TODO pt distinguish which flag to give more accurate error report
00806                 // error: invalid specifier in typedef
00807                 report << invalid_specifier_typedef << declarator->location_get();
00808         }
00809         
00810         sa_simple_declaration_logger << "extracting the ss_type from declarator\n" << msg::eolog;
00811         
00812         // extract the plain type
00813         ptr<sa_declarator_type> sdt = sa_declarator_type::create();
00814         ptr<ss_type> type = sdt->process(specifiers->type_get(),declarator);
00815 
00816         sa_simple_declaration_logger << "converting the name\n" << msg::eolog;
00817 
00818         ptr<as_name> name = declarator->name_get();
00819 
00820         // get the ss equivalent of the name
00821         ptr<ss_decl_name> decl_name = as_id_to_ss_decl_name::instance()->process(name->identifier_get());
00822         ptr<ss_decl_seq> current_scope = ctx->ss_get()->scope_get();
00823 
00824         // get the declarations in current scope
00825         ptr<ss_declaration_set_type> decls = li_by_name_in_single_scope::instance()->process(decl_name,current_scope);
00826 
00827         if (decls->size()) {
00828                 sa_simple_declaration_logger << "found some declarations\n" << msg::eolog;
00829 
00830                 // check any of the found, because they must be consistent
00831                 ptr<ss_declaration> found_decl = *(decls->begin());
00832         
00833                 /* TODO pt remove
00834         for (ss_declaration_set_type::iterator it = decls->begin(), end = decls->end();
00835                         it != end; ++it) {
00836                 ptr<ss_declaration> one = *it;
00837 
00838                  TODO pt this is wrong?
00839                 if (one->contained_in_get() == current_scope) {
00840                         sa_simple_declaration_logger << "found declaration in current scope\n" << msg::eolog;
00841                 */
00842 
00843                 ptr<ss_typedef_definition> td = ss_declaration2ss_typedef_definition::instance()->process(found_decl);
00844 
00845                 if (td) {
00846                         sa_simple_declaration_logger << "the declaration is typedef\n" << msg::eolog;
00847 
00848                         if (type == td->type_get()) {
00849                                 sa_simple_declaration_logger << "both types are the same\n" << msg::eolog;
00850                         } else {
00851                                 sa_simple_declaration_logger << "error: the types are different\n" << msg::eolog;
00852                                 // error: name typedef conflict with previous typedef
00853                                 report << conflicting_types << declarator->location_get();
00854                                 report << previous_declaration << td->location_get();
00855                         }
00856                 } else {
00857                         // error: name redeclared as different kind of symbol
00858                         sa_simple_declaration_logger << "error: the declaration is different from typedef\n" << msg::eolog;
00859                         report << redeclaration_different << declarator->location_get();
00860                         report << previous_declaration << found_decl->location_get();
00861                 }
00862                 
00863         } else {
00864         
00865                 ptr<source_location> loc = declarator->location_get();
00866                 ptr<ss_declaration_time> dt = ss_declaration_time::create(loc->order_get());
00867 
00868                 sa_simple_declaration_logger << "creating the typedef definition\n" << msg::eolog;
00869 
00870                 // create the typedef
00871                 ptr<ss_declaration> type_definition = ss_typedef_definition::create(
00872                         loc, // location
00873                         dt, // visible since
00874                         dt, // declaration time
00875                         decl_name, // declaration name
00876                         current_scope, // contained in
00877                         type, // ss type
00878                         ss_linkage::create("C++",ss_linkage::LINKAGE_NO), // linkage
00879                         ctx->ss_get()->access_specifier_get(), // access specifier
00880                         ss_storage_class::ST_TYPEDEF // storage class
00881                         );
00882 
00883                 sa_simple_declaration_logger << "adding the typedef definition to current scope\n" << msg::eolog;
00884 
00885                 // add the typedef into the current scope
00886                 current_scope->contents_get()->push_back(type_definition);
00887 
00888                 // TODO pt remove
00889                 sa_simple_declaration_logger << "announce new declaration\n" << msg::eolog;
00890                 // TMA: make the declaration known to egg
00891                 declaration_finished->broadcast(type_definition);
00892 
00893         }
00894 
00895         sa_simple_declaration_logger << "sa_simple_declaration::process_typedef() end\n" << msg::eolog;
00896 }
00897 
00898 
00899 end_package(sem);
00900 end_package(cplus);
00901 end_package(lang);
00902 end_package(lestes);
00903 

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