Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

function_body.cc

Go to the documentation of this file.
00001 // AUTOMATICALLY GENERATED -- DO NOT EDIT!         -*- c++ -*-
00002 
00003 #include "function_body.h"
00004 #include "function_body_i.h"
00005 
00006 
00007 #line 103 "function_body.cpp"
00008 /******************************* Functions *******************************/
00009 
00017 static Ptree*
00018 process_initializers(Function_signature* fsig, Block_scope* scope, Ptree* tree);
00019 
00020 #line 50 "function_body.cpp"
00021 
00024 Function_body_queue::Function_body_queue()
00025     : first(0), last(0)
00026 { }
00027 
00028 #line 56 "function_body.cpp"
00029 
00035 void
00036 Function_body_queue::add_function(Function_signature* fsig,
00037                                   Block_scope* scope,
00038                                   Ptree* tree,
00039                                   Ptree* init)
00040 {
00041     assert(fsig);
00042     assert(scope);
00043     assert(tree);
00044     assert(!init || fsig->get_function()->get_function_kind() == Symbol_name::k_Constructor);
00045 
00046     Function_body_node* p = new Function_body_node(fsig, scope, tree, init);
00047     if (first)
00048         last->next = p;
00049     else
00050         first = p;
00051     last = p;
00052 }
00053 
00054 #line 80 "function_body.cpp"
00055 
00056 Function_body_node*
00057 Function_body_queue::pop()
00058 {
00059     Function_body_node* rv = first;
00060     if (first) {
00061         first = first->next;
00062         if (!first)
00063             last = 0;
00064     }
00065     return rv;
00066 }
00067 
00068 #line 92 "function_body.cpp"
00069 
00071 void
00072 Function_body_queue::process()
00073 {
00074     while (Function_body_node* p = pop()) {
00075         process_function_body(p->fsig, p->scope, p->tree, p->init);
00076         delete p;
00077     }
00078 }
00079 
00080 #line 102 "function_body.cpp"
00081 
00082 /******************************* Functions *******************************/
00083 
00091 static Ptree*
00092 process_initializers(Function_signature* fsig, Block_scope* scope, Ptree* tree)
00093 {
00094     /* cut off the ":" */
00095     if (tree) {
00096         expect_ptree(tree->Car(), ':');
00097         tree = tree->Cdr();
00098     }
00099 
00100     /* the scopes we work in */
00101     Abstract_scope* class_scope = fsig->get_function()->get_declared_scope();
00102     Class_symbol* class_sym = downcast<Class_symbol*>(fsig->get_this_type().get_type_symbol());
00103 
00104     /* what we do: we parse the initializer into an array. Then, we
00105        gather them up in the order in which they'll be executed and
00106        null them out. If some remain, we have a bug. */
00107     std::vector<std::pair<Symbol*, Ptree*> > inits;
00108     for (Ptree* p = tree; p; (p = p->Cdr()) && (p = p->Cdr())) {
00109         Ptree* ele = p->Car();
00110         expect_ptree(ele->Second(), '(');
00111         expect_ptree(ele->Nth(3), ')');
00112         // FIXME: 12.6.2p2 says first look into class_scope, then
00113         // the scope in which the ctor is defined
00114         Symbol_pair sp = Symbol_name(ele->First(), class_scope, false).lookup_for_use(false);
00115 
00116         Symbol* the_sym = 0;
00117         if (Class_symbol* csym = dynamic_cast<Class_symbol*>(sp.tag))
00118             the_sym = csym;
00119         else if (Variable_symbol* vsym = dynamic_cast<Variable_symbol*>(sp.untag))
00120             the_sym = vsym;
00121         else if (Typedef_symbol* tdsym = dynamic_cast<Typedef_symbol*>(sp.untag)) {
00122             Type t = tdsym->get_type();
00123             if (t.is_class_type())
00124                 the_sym = t.get_type_symbol();
00125         }
00126 
00127         if (!the_sym)
00128             compile_error("don't know what to do with name `" + std::string(ele->First()->ToString()) + "` in an initializer");
00129 
00130         inits.push_back(std::make_pair(the_sym, ele->Cdr()));
00131     }
00132 
00133     /* Now we have all the initializers. What do we want to initialize? */
00134     std::vector<Symbol*> want;
00135     for (Class_symbol::bases_t::const_iterator i = class_sym->vbc_begin(); i != class_sym->vbc_end(); ++i)
00136         want.push_back(*i);
00137     for (Class_symbol::bases_t::const_iterator i = class_sym->base_begin(); i != class_sym->base_end(); ++i)
00138         want.push_back(*i);
00139     for (Class_symbol::members_t::const_iterator i = class_sym->mem_begin(); i != class_sym->mem_end(); ++i)
00140         if ((*i)->is_member_variable())
00141             want.push_back(*i);
00142 
00143     /* Let's boogie. */
00144     Ptree* output_list = 0;
00145     unsigned last_used = 0;
00146     for (unsigned i = 0; i < want.size(); ++i) {
00147         /* first, look up the corresponding initializer and strike it out. */
00148         Ptree* the_init = 0;
00149         for (unsigned j = 0; j < inits.size(); ++j) {
00150             if (inits[j].first == want[i]) {
00151                 if (the_init) {
00152                     compile_warning("multiple initializers for `" + want[i]->get_name() + "'", the_init);
00153                 } else {
00154                     if (last_used > j)
00155                         compile_warning("initializers will be re-ordered to match initialisation rules", the_init);
00156                     the_init = inits[j].second;
00157                     last_used = j;
00158                 }
00159                 inits[j].first = 0;
00160             }
00161         }
00162 
00163         /* do it. */
00164         Ptree *output_init, *output_name;
00165         if (Class_symbol* csym = dynamic_cast<Class_symbol*>(want[i])) {
00166             output_init = Init_handler(scope, the_init, false).process_initializer(csym->get_type());
00167             output_name = make_name(csym->get_name(), csym->get_type(), csym);
00168         } else if (Variable_symbol* vsym = dynamic_cast<Variable_symbol*>(want[i])) {
00169             output_init = Init_handler(scope, the_init, false).process_initializer(vsym->get_type());
00170             if (!output_init)
00171                 compile_warning("member `" + vsym->get_name() + "' not initialized", tree);
00172             output_name = make_name(vsym);
00173         } else {
00174             assert(!"game over");
00175         }
00176 
00177         /* build output tree */
00178         output_list = Ptree::Snoc(output_list,
00179                                   Ptree::List(output_name,
00180                                               make_static_leaf("="),
00181                                               output_init));
00182     }
00183 
00184     /* everything done? */
00185     for (unsigned i = 0; i < inits.size(); ++i)
00186         if (inits[i].first)
00187             compile_error("unexpected initializer for `" + inits[i].first->get_name() + "'");
00188 
00189     return output_list;
00190 }
00191 
00192 #line 212 "function_body.cpp"
00193 
00199 void
00200 process_function_body(Function_signature* fsig, Block_scope* scope,
00201                       Ptree* tree, Ptree* init)
00202 {
00203     if (fsig->get_storage_specifier() == s_Member)
00204         scope->set_this_type(fsig->get_this_type());
00205     else
00206         scope->set_this_type(Type());
00207 
00208     // maybe it's a constructor
00209     if (fsig->get_function()->get_function_kind() == Symbol_name::k_Constructor)
00210         init = process_initializers(fsig, scope, init);
00211     else
00212         assert(!init);
00213 
00214     // this assumes that the tree is a PtreeBlock or a simple statement
00215     Annotator anno(&Source::instance(), scope);
00216     anno.visit_stmt_or_block(tree);
00217     fsig->set_body(anno.get_output(), init);
00218 }

Generated on Mon Feb 10 17:32:49 2003 for VFiasco Semantics Compiler by doxygen1.2.15