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

class.cc

Go to the documentation of this file.
00001 // AUTOMATICALLY GENERATED -- DO NOT EDIT!         -*- c++ -*-
00002 
00003 #include "class.h"
00004 #include "class_i.h"
00005 
00006 
00007 #line 422 "class.cpp"
00008 /************************************************************************/
00009 
00010 static void
00011 process_base_classes(Class_symbol* sym, Ptree* tree, Abstract_scope* scope);
00012 
00013 #line 728 "class.cpp"
00014 
00016 static bool
00017 is_static(Symbol* sym);
00018 
00019 #line 840 "class.cpp"
00020 static bool
00021 is_covariant_or_same(Type n, Type o);
00022 
00023 #line 75 "class.cpp"
00024 
00025 Class_symbol*
00026 Default_class_adder::add_class(Abstract_scope* scope, std::string name, Symbol::Kind k)
00027 {
00028     Class_symbol* sym = new Class_symbol(k, scope, name);
00029     sym->set_status(Symbol::st_Declared);
00030     scope->add_symbol(name, sym);
00031     return sym;
00032 }
00033 
00034 #line 84 "class.cpp"
00035 
00036 /****************************** Class_symbol *****************************/
00037 
00038 
00039 Class_symbol::Class_symbol(Kind k, Abstract_scope* in_scope, std::string real_name)
00040     : k(k), in_scope(in_scope), real_name(real_name), pod(true), aggregate(true)
00041 { }
00042 
00043 #line 91 "class.cpp"
00044 
00045 
00046 Class_symbol::~Class_symbol()
00047 { }
00048 
00049 #line 95 "class.cpp"
00050 
00051 Symbol::Kind
00052 Class_symbol::get_kind() const
00053 {
00054     return k;
00055 }
00056 
00057 #line 119 "class.cpp"
00058 
00059 bool
00060 Class_symbol::is_base_class_of(Class_symbol* other) const
00061 {
00062     bases_t::iterator i;
00063     for (i = other->base_classes.begin(); i != other->base_classes.end(); ++i)
00064         if (*i == this || is_base_class_of(*i))
00065             return true;
00066 
00067     for (i = other->virtual_base_classes.begin(); i != other->virtual_base_classes.end(); ++i)
00068         if (*i == this || is_base_class_of(*i))
00069             return true;
00070 
00071     return false;
00072 }
00073 
00074 #line 134 "class.cpp"
00075 
00076 bool
00077 Class_symbol::is_unique_base_class_of(Class_symbol* other) const
00078 {
00079     // FIXME
00080     return is_base_class_of(other);
00081 }
00082 
00083 #line 141 "class.cpp"
00084 
00085 void
00086 Class_symbol::enumerate_base_classes(bool with_virtuals, bases_t* output)
00087 {
00088     bases_t::iterator i;
00089     for (i = base_classes.begin(); i != base_classes.end(); ++i) {
00090         output->push_back(*i);
00091         (*i)->enumerate_base_classes(false, output);
00092     }
00093 
00094     if (with_virtuals) {
00095         for (i = virtual_base_classes.begin(); i != virtual_base_classes.end(); ++i) {
00096             output->push_back(*i);
00097             (*i)->enumerate_base_classes(false, output);
00098         }
00099     }
00100 }
00101 
00102 #line 158 "class.cpp"
00103 
00105 void
00106 Class_symbol::maybe_add_vbc(Class_symbol* sym)
00107 {
00108     if (std::find(base_classes.begin(), base_classes.end(), sym) != base_classes.end())
00109         compile_error("`" + sym->get_name() + "' is already a nonvirtual base class");
00110     if (std::find(virtual_base_classes.begin(), virtual_base_classes.end(), sym) == virtual_base_classes.end()) {
00111         virtual_base_classes.push_back(sym);
00112         for (bases_t::iterator i = sym->virtual_base_classes.begin(); i != sym->virtual_base_classes.end(); ++i)
00113             maybe_add_vbc(*i);
00114     }
00115 }
00116 
00117 #line 171 "class.cpp"
00118 
00122 void
00123 Class_symbol::add_base_class(Class_symbol* sym, bool is_virt)
00124 {
00125     if (!sym || !sym->is_defined())
00126         compile_error("base class `" + sym->get_name() + "' is not defined");
00127     if (sym->get_kind() != k_ClassOrStruct)
00128         compile_error("base class must be class or struct");
00129 
00130     if (is_virt) {
00131         maybe_add_vbc(sym);
00132     } else {
00133         if (std::find(virtual_base_classes.begin(), virtual_base_classes.end(), sym) != virtual_base_classes.end())
00134             compile_error("`" + sym->get_name() + "' is already a virtual base class");
00135         if (std::find(base_classes.begin(), base_classes.end(), sym) != base_classes.end())
00136             compile_error("`" + sym->get_name() + "' is already a nonvirtual base class");
00137         base_classes.push_back(sym);
00138         for (bases_t::iterator i = sym->virtual_base_classes.begin(); i != sym->virtual_base_classes.end(); ++i)
00139             maybe_add_vbc(*i);
00140     }
00141     pod = aggregate = false;
00142 }
00143 
00144 #line 196 "class.cpp"
00145 
00146 void
00147 Class_symbol::dump(std::ostream& os)
00148 {
00149     Type_symbol::dump(os);
00150     if (!base_classes.empty()) {
00151         os << "\n  + base classes:";
00152         for (unsigned i = 0; i < base_classes.size(); ++i)
00153             os << " " << base_classes[i]->get_name();
00154     }
00155     if (!virtual_base_classes.empty()) {
00156         os << "\n  + virtual base classes:";
00157         for (unsigned i = 0; i < virtual_base_classes.size(); ++i)
00158             os << " " << virtual_base_classes[i]->get_name();
00159     }
00160 }
00161 
00162 #line 220 "class.cpp"
00163 
00164 Class_scope*
00165 Class_symbol::get_scope()
00166 {
00167     return new Class_scope(this);
00168 }
00169 
00170 #line 262 "class.cpp"
00171 
00173 void
00174 Class_symbol::start_definition(std::string basename)
00175 {
00176     if (basename.length()) {
00177         Class_scope scope(this);
00178         Typedef_symbol* tdsym = new Typedef_symbol(get_type());
00179         scope.add_symbol(basename, tdsym);
00180         Symbol_table::get_instance().set_peer(tdsym, this);
00181     }
00182 }
00183 
00184 #line 274 "class.cpp"
00185 
00187 void
00188 Class_symbol::finish_definition()
00189 {
00190     /* aggregate? */
00191     Function_symbol* fsym = dynamic_cast<Function_symbol*>(lookup_helper(Symbol_name::CONSTRUCTOR_NAME).untag);
00192     if (fsym) {
00193         pod = aggregate = false;
00194     } else {
00195         /* no default constructor */
00196         Class_scope* cs = get_scope();
00197         fsym = new Function_symbol(cs, Symbol_name::k_Constructor);
00198         cs->add_symbol(Symbol_name::CONSTRUCTOR_NAME, fsym);
00199     }
00200 
00201     /* add copy constructor */
00202     if (!get_copy_ctor(fsym, true)) {
00203         Type t = get_type();
00204         if (implicit_copy_ctor_is_const())
00205             t.add_qualifier(Type::q_Const);
00206         Function_signature* fsig =
00207             fsym->add_signature(make_unary_function_type(t.make_reference_type(), ctor_type),
00208                                 get_type(),
00209                                 s_Member,
00210                                 f_Inline,
00211                                 Function_symbol::must_be_new);
00212         fsig->set_generated();
00213     }
00214 
00215     /* assignment operator */
00216     fsym = dynamic_cast<Function_symbol*>(lookup_helper(Symbol_name::ASSIGNMENT_OPERATOR_NAME).untag);
00217     if (!get_copy_ctor(fsym, false)) {
00218         Assignment_operator aso = implicit_assignment_operator_style();
00219         if (aso != no_assignment_operator) {
00220             if (!fsym) {
00221                 Class_scope* cs = get_scope();
00222                 fsym = new Function_symbol(cs, Symbol_name::k_Operator);
00223                 cs->add_symbol(Symbol_name::ASSIGNMENT_OPERATOR_NAME, fsym);
00224             }
00225             Type t = get_type();
00226             if (aso == const_assignment_operator)
00227                 t.add_qualifier(Type::q_Const);
00228             Function_signature* fsig =
00229                 fsym->add_signature(make_unary_function_type(t.make_reference_type(),
00230                                                              get_type().make_reference_type()),
00231                                     get_type(),
00232                                     s_Member,
00233                                     f_Inline,
00234                                     Function_symbol::must_be_new);
00235             fsig->set_generated();
00236         }
00237     }
00238 
00239     /* fill in member function names */
00240     for (memfuns_t::iterator i = member_functions.begin(); i != member_functions.end(); ++i)
00241         (*i)->fill_in_mangled_names(true);
00242 }
00243 
00244 #line 332 "class.cpp"
00245 
00249 Function_signature*
00250 Class_symbol::get_copy_ctor(Function_symbol* fsym, bool must_be_ref) const
00251 {
00252     if (!fsym)
00253         return 0;
00254     for (Function_symbol::Sig_it i = fsym->sig_begin(); i != fsym->sig_end(); ++i) {
00255         Type t = (*i)->get_proto_type();
00256         if (t.get_num_function_args() == 1
00257             && (!must_be_ref || t.get_function_arg(0).get_kind() == Type::k_Reference)
00258             && t.get_function_arg(0).sans_reference().is_same_unqualified_type(get_type()))
00259             return *i;
00260     }
00261     return 0;
00262 }
00263 
00264 #line 350 "class.cpp"
00265 
00266 bool
00267 Class_symbol::implicit_copy_ctor_is_const() const
00268 {
00269     /* The question we're asking is: does our copy ctor take a "const"
00270        arg or not? */
00271     for (bases_t::const_iterator i = base_classes.begin(); i != base_classes.end(); ++i)
00272         if (Function_signature* fsig = (*i)->get_copy_ctor(dynamic_cast<Function_symbol*>((*i)->lookup_helper(Symbol_name::CONSTRUCTOR_NAME).untag), true))
00273             if (!fsig->get_proto_type().get_function_arg(0).get_basis_type().is_qualified(Type::q_Const))
00274                 return false;
00275     for (bases_t::const_iterator i = virtual_base_classes.begin(); i != virtual_base_classes.end(); ++i)
00276         if (Function_signature* fsig = (*i)->get_copy_ctor(dynamic_cast<Function_symbol*>((*i)->lookup_helper(Symbol_name::CONSTRUCTOR_NAME).untag), true))
00277             if (!fsig->get_proto_type().get_function_arg(0).get_basis_type().is_qualified(Type::q_Const))
00278                 return false;
00279     for (members_t::const_iterator i = mem_begin(); i != mem_end(); ++i) {
00280         if ((*i)->is_member_variable()) {
00281             Type t = (*i)->get_type().sans_array();
00282             if (t.is_class_type()) {
00283                 Class_symbol* csym = downcast<Class_symbol*>(t.get_type_symbol());
00284                 if (Function_signature* fsig = csym->get_copy_ctor(dynamic_cast<Function_symbol*>(csym->lookup_helper(Symbol_name::CONSTRUCTOR_NAME).untag), true))
00285                     if (!fsig->get_proto_type().get_function_arg(0).get_basis_type().is_qualified(Type::q_Const))
00286                         return false;
00287             }
00288         }
00289     }
00290     return true;
00291 }
00292 
00293 #line 377 "class.cpp"
00294 
00295 Class_symbol::Assignment_operator
00296 Class_symbol::implicit_assignment_operator_style() const
00297 {
00298     /* if one of our members or bases has no assignment operator, we don't
00299        have one either. If one of our members or bases has a nonconst
00300        assignment operator, ours is nonconst, too. If we have reference or
00301        const members, we can't have an assignment operator. */
00302     Assignment_operator rv = const_assignment_operator;
00303     for (bases_t::const_iterator i = base_classes.begin(); i != base_classes.end(); ++i) {
00304         if (Function_signature* fsig = (*i)->get_copy_ctor(dynamic_cast<Function_symbol*>((*i)->lookup_helper(Symbol_name::ASSIGNMENT_OPERATOR_NAME).untag), false)) {
00305             if (!fsig->get_proto_type().get_function_arg(0).get_basis_type().is_qualified(Type::q_Const))
00306                 rv = nonconst_assignment_operator;
00307         } else {
00308             return no_assignment_operator;
00309         }
00310     }
00311     for (bases_t::const_iterator i = virtual_base_classes.begin(); i != virtual_base_classes.end(); ++i) {
00312         if (Function_signature* fsig = (*i)->get_copy_ctor(dynamic_cast<Function_symbol*>((*i)->lookup_helper(Symbol_name::ASSIGNMENT_OPERATOR_NAME).untag), false)) {
00313             if (!fsig->get_proto_type().get_function_arg(0).get_basis_type().is_qualified(Type::q_Const))
00314                 rv = nonconst_assignment_operator;
00315         } else {
00316             return no_assignment_operator;
00317         }
00318     }
00319 
00320     for (members_t::const_iterator i = mem_begin(); i != mem_end(); ++i) {
00321         if ((*i)->is_member_variable()) {
00322             Type t = (*i)->get_type().sans_array();
00323             if (t.is_qualified(Type::q_Const) || t.get_kind() == Type::k_Reference)
00324                 return no_assignment_operator;
00325             if (t.is_class_type()) {
00326                 Class_symbol* csym = downcast<Class_symbol*>(t.get_type_symbol());
00327                 if (Function_signature* fsig = csym->get_copy_ctor(dynamic_cast<Function_symbol*>(csym->lookup_helper(Symbol_name::ASSIGNMENT_OPERATOR_NAME).untag), false)) {
00328                     if (!fsig->get_proto_type().get_function_arg(0).get_basis_type().is_qualified(Type::q_Const))
00329                         rv = nonconst_assignment_operator;
00330                 } else {
00331                     return no_assignment_operator;
00332                 }
00333             }
00334         }
00335     }
00336     return rv;
00337 }
00338 
00339 #line 421 "class.cpp"
00340 
00341 /************************************************************************/
00342 
00343 static void
00344 process_base_classes(Class_symbol* sym, Ptree* tree, Abstract_scope* scope)
00345 {
00346     expect_ptree(tree->First(), ':');
00347     for (Ptree* p = tree->Cdr(); p != 0; (p = p->Cdr()) && (p = p->Cdr())) {
00348         Ptree* base = p->Car();
00349         assert(!base->IsLeaf());
00350 
00351         /* parse it */
00352         bool is_virt = false;
00353         while (1) {
00354             switch (base->Car()->What()) {
00355              case VIRTUAL:
00356                 is_virt = true;
00357                 break;
00358              case PUBLIC:
00359              case PRIVATE:
00360              case PROTECTED:
00361                 break;
00362              default:
00363                 goto out;
00364             }
00365             base = base->Cdr();
00366             assert(base);
00367         }
00368      out:
00369         assert(!base->Cdr());
00370         Symbol_pair p = Symbol_name(base->Car(), scope, false).lookup_for_use(false);
00371         if (!p.tag || p.tag->get_kind() != Symbol::k_ClassOrStruct)
00372             compile_error("invalid base class specified");
00373         sym->add_base_class(downcast<Class_symbol*>(p.tag), is_virt);
00374     }
00375 }
00376 
00377 #line 457 "class.cpp"
00378 
00379 /* content is:
00380    [kind name]
00381    [kind name bases content]
00382    [kind [nil nil] content] (!) */
00383 Class_symbol*
00384 parse_class(Ptree* tree, Abstract_scope* scope, Ptree* name_for_anon,
00385             bool is_type_declaration, Class_adder& adder)
00386 {
00387     /* Figure out kind */
00388     Ptree* rw = tree->First();
00389     Symbol::Kind k;
00390     if (rw->Eq("class") || rw->Eq("struct"))
00391         k = Symbol::k_ClassOrStruct;
00392     else if (rw->Eq("union"))
00393         k = Symbol::k_Union;
00394     else
00395         bogus_ptree_error("expected struct/class/union", tree->First());
00396 
00397     if (tree->Length() == 2) {
00398         /* Declaration / reference to existing */
00399         Ptree* name = tree->Second();
00400         if (!name)
00401             bogus_ptree_error("stray struct/class/union in program", tree);
00402 
00403         Symbol_name sym_name(name, scope, false);
00404         Symbol_pair p = sym_name.lookup_for_decl();
00405         if (p.tag) {
00406             /* already defined. */
00407             if (p.tag->get_kind() != k)
00408                 compile_error("symbol `" + std::string(name->ToString()) + "' already is a different kind of symbol");
00409             Class_symbol* csym = dynamic_cast<Class_symbol*>(p.tag);
00410             if (!csym)
00411                 compile_error("symbol `" + std::string(name->ToString()) + "' is not a class");
00412             if (!csym->is_declared())
00413                 csym->set_status(Symbol::st_Declared);
00414             return csym;
00415         } else {
00416             /* not defined yet. Declare it. If this is a type declaration,
00417                declare it here. Otherwise, declare it in smallest enclosing
00418                non-class, non-prototype scope. */
00419             if (sym_name.is_qualified())
00420                 compile_error("can't declare scoped identifier");
00421             if (sym_name.is_template())
00422                 compile_error("reference to undefined template");
00423             if (!is_type_declaration) {
00424                 // prototype scope should also be handled here, but we
00425                 // don't do prototype scope.
00426                 while (scope && dynamic_cast<Class_scope*>(scope))
00427                     scope = scope->get_parent();
00428                 // there's always a namespace scope outside
00429                 assert(scope);
00430             }
00431 
00432             return adder.add_class(scope, sym_name.get_name(), k);
00433         }
00434     }
00435 
00436     /* When we're here, it is a class definition */
00437     Class_symbol* csym;
00438     Ptree* name = tree->Second();
00439     Ptree* body;
00440     Ptree* bases;
00441 
00442     /* bummer. Named objects are "[key name base defn]",
00443        unnamed ones are "[key [nil nil] defn]". */
00444     if (name && !name->IsLeaf() && !name->Car()) {
00445         name = bases = 0;
00446         body = tree->Third();
00447     } else {
00448         bases = tree->Third();
00449         body = tree->Nth(3);
00450     }
00451     if (!name)
00452         name = name_for_anon;
00453 
00454     Symbol_name sym_name(name, scope, false);
00455     Symbol_pair p = sym_name.lookup_for_decl();
00456     if (p.tag) {
00457         if (p.tag->get_kind() != k)
00458             compile_error("symbol `" + std::string(name->ToString()) + "' already is a different kind of symbol");
00459         csym = downcast<Class_symbol*>(p.tag);
00460     } else {
00461         if (sym_name.is_qualified())
00462             compile_error("can't declare scoped identifier");
00463         if (sym_name.is_template())
00464             compile_error("definition of template specialisation not supported");
00465         csym = adder.add_class(scope, sym_name.get_name(), k);
00466     }
00467 
00468     if (csym->is_defined())
00469         compile_error("We already have a perfectly good definition for `" + csym->get_name() + "'");
00470     if (!csym->is_declared())
00471         csym->set_status(Symbol::st_Declared);
00472 
00473     /* read definition... */
00474     if (bases)
00475         process_base_classes(csym, bases, scope);
00476     if (body) {
00477         /* [{ [a b c d] }] */
00478         csym->start_definition(sym_name.get_name());
00479         expect_ptree(body->First(), '{');
00480         expect_ptree(body->Third(), '}');
00481         Annotator ann(&Source::instance(), csym->get_scope());
00482         for (Ptree* p = body->Second(); p; p = p->Cdr())
00483             ann.visit_and_catch(p->Car());
00484         csym->finish_definition();
00485     }
00486 
00487     /* finish it up */
00488     csym->set_status(Symbol::st_Defined);
00489     return csym;
00490 }
00491 
00492 #line 570 "class.cpp"
00493 
00494 /************************** Class_lookup_helper **************************/
00495 
00523 Class_lookup_helper::Class_lookup_helper()
00524 { }
00525 
00526 #line 602 "class.cpp"
00527 
00528 
00529 Class_lookup_helper::~Class_lookup_helper()
00530 { }
00531 
00532 #line 606 "class.cpp"
00533 
00535 void
00536 Class_lookup_helper::add_class(Class_symbol* sym)
00537 {
00538     typedef Class_symbol::bases_t::iterator iter_t;
00539     if (predicate(sym)) {
00540         /* this class defines the symbol. All its base classes are
00541            hidden.  Hence, we need not process the non-virtual base
00542            class sub-objects. Add the VBCs to the set of hidden base
00543            classes. */
00544         result_set.push_back(sym);
00545         for (iter_t i = sym->virtual_base_classes.begin(); i != sym->virtual_base_classes.end(); ++i)
00546             if (find(hidden_vbcs.begin(), hidden_vbcs.end(), *i) == hidden_vbcs.end())
00547                 hidden_vbcs.push_back(*i);
00548     } else {
00549         /* symbol not defined here. Maybe in one of the bases? */
00550         for (iter_t i = sym->base_classes.begin(); i != sym->base_classes.end(); ++i)
00551             add_class(*i);
00552         /* VBCs are processed later */
00553     }
00554 }
00555 
00556 #line 628 "class.cpp"
00557 
00560 void
00561 Class_lookup_helper::finish(Class_symbol* sym)
00562 {
00563     typedef Class_symbol::bases_t::iterator iter_t;
00564 
00565     for (iter_t i = sym->virtual_base_classes.begin(); i != sym->virtual_base_classes.end(); ++i)
00566         if (predicate(*i) && find(hidden_vbcs.begin(), hidden_vbcs.end(), *i) == hidden_vbcs.end())
00567             result_set.push_back(*i);
00568 }
00569 
00570 #line 646 "class.cpp"
00571 
00572 
00573 Class_name_lookup_helper::Class_name_lookup_helper(std::string name)
00574     : name(name)
00575 { }
00576 
00577 #line 651 "class.cpp"
00578 
00579 
00580 Class_name_lookup_helper::~Class_name_lookup_helper()
00581 { }
00582 
00583 #line 655 "class.cpp"
00584 
00585 bool
00586 Class_name_lookup_helper::predicate(Class_symbol* sym)
00587 {
00588     return sym->lookup_helper(name);
00589 }
00590 
00591 #line 661 "class.cpp"
00592 
00594 Symbol_pair
00595 Class_name_lookup_helper::get_result()
00596 {
00597     typedef classes_t::iterator iter_t;
00598 
00599     Symbol_pair result;
00600     Class_symbol *untag_class = 0, *tag_class = 0;
00601     for (iter_t i = result_set.begin(); i != result_set.end(); ++i) {
00602         Symbol_pair p = (*i)->lookup_helper(name);
00603 
00604         /* check "normal" member */
00605         assert(p.untag);
00606         if (untag_class) {
00607             if (*i != untag_class || !is_static(p.untag))
00608                 compile_error("ambiguous: " + name);
00609         } else {
00610             untag_class = *i;
00611             result.untag = p.untag;
00612         }
00613 
00614         /* check "tag" member */
00615         if (p.tag) {
00616             if (tag_class) {
00617                 if (*i != tag_class || !is_static(p.tag))
00618                     compile_error("ambiguous: class/enum " + name);
00619             } else {
00620                 tag_class = *i;
00621                 result.tag = p.tag;
00622             }
00623         }
00624     }
00625 
00626     return result;
00627 }
00628 
00629 #line 697 "class.cpp"
00630 
00631 /****************************** Class_scope ******************************/
00632 
00633 
00634 Class_scope::Class_scope(Class_symbol* sym)
00635     : Abstract_scope(sym->in_scope), sym(sym),
00636       prefix(Symbol_name::get_mangled_scope_from_symbol(sym->get_name()))
00637 { }
00638 
00639 #line 705 "class.cpp"
00640 
00641 
00642 Class_scope::~Class_scope()
00643 { }
00644 
00645 #line 715 "class.cpp"
00646 
00647 Type
00648 Class_scope::get_this_type() const
00649 {
00650     return Type();
00651 }
00652 
00653 #line 721 "class.cpp"
00654 
00655 std::string
00656 Class_scope::get_unique_name(std::string name)
00657 {
00658     return Symbol_name::get_mangled_symbol_name(prefix, name);
00659 }
00660 
00661 #line 727 "class.cpp"
00662 
00665 static bool
00666 is_static(Symbol* sym)
00667 {
00668     /* allow: static variables, enumerators, nested types */
00669     // FIXME? I think this doesn't apply to member functions.
00670     switch(sym->get_kind()) {
00671      case Symbol::k_Enum:
00672      case Symbol::k_ClassOrStruct:
00673      case Symbol::k_Union:
00674      case Symbol::k_Typedef:
00675      case Symbol::k_ClassTemplate:
00676         return true;
00677      case Symbol::k_Variable:
00678         {
00679             Variable_symbol* vsym = downcast<Variable_symbol*>(sym);
00680             return vsym->get_storage_class() == s_Static
00681                 || !vsym->has_address();
00682         }
00683      case Symbol::k_Namespace:
00684      case Symbol::k_Function:
00685         ;
00686     }
00687     return false;
00688 }
00689 
00690 #line 754 "class.cpp"
00691 
00693 Symbol_pair
00694 Class_scope::lookup_here(std::string name, bool for_decl)
00695 {
00696     if (Symbol_pair p = sym->lookup_helper(name))
00697         return p;
00698 
00699     if (for_decl)
00700         return Symbol_pair();
00701 
00702     /* not a declaration. search base classes. */
00703     Class_name_lookup_helper h(name);
00704     h.add_class(sym);
00705     h.finish(sym);
00706     return h.get_result();
00707 }
00708 
00709 #line 771 "class.cpp"
00710 
00711 void
00712 Class_scope::add_symbol(std::string name, Symbol* sym)
00713 {
00714     // Symbol_table::get_instance().add_symbol(prefix + name, name.length(), sym);
00715     Symbol_table::get_instance().add_symbol(get_unique_name(name), name.length(), sym);
00716 }
00717 
00718 #line 778 "class.cpp"
00719 
00721 Variable_symbol*
00722 Class_scope::add_variable(Storage_class_specifier storage,
00723                           Type type, Ptree* name, Ptree* init, Ptree* bitsize)
00724 {
00725     assert(type.get_kind() != Type::k_Function);
00726 
00727     Symbol_name sym_name(name, this, false);
00728     if (sym_name.is_qualified())
00729         compile_error("can't define structured names inside a class");
00730     if (sym_name.is_template())
00731         compile_error("can't define template specialisation");
00732 
00733     if (storage == s_None)
00734         storage = s_Member;
00735     if (storage != s_Member && storage != s_Mutable && storage != s_Static)
00736         compile_error("invalid storage class for member variable");
00737     if (storage == s_Mutable && type.is_qualified(Type::q_Const))
00738         compile_error("`mutable const' is not sensible");
00739 
00740     if (init) {
00741         if (storage == s_Static && (type.is_int() || type.is_enum_type()) && type.is_qualified(Type::q_Const))
00742             /* allowed, 9.4.2p4 */;
00743         else
00744             compile_error("can't initialize member " + sym_name.get_name() + " of class " + sym->get_name());
00745         init = Init_handler(this, init, true).process_initializer(type);
00746     }
00747 
00748     Symbol_pair pair = sym_name.lookup_for_decl();
00749     if (pair && pair.tag != pair.untag)
00750         compile_error("`" + sym_name.get_name() + "' already defined");
00751 
00752     if (storage == s_Static) {
00753         /* static variables. These get storage class "extern" because
00754            they are externally visible. Plus, an initializer
00755            contributes to the semantics of the program. */
00756         Variable_symbol* vsym
00757             = new Variable_symbol(type, s_Extern, init, bitsize,
00758                                   init ? Symbol::st_Defined : Symbol::st_Declared);
00759         add_symbol(sym_name.get_name(), vsym);
00760         sym->members.push_back(vsym);
00761         return vsym->is_defined() ? vsym : 0;
00762     } else {
00763         /* members. These are always defined. */
00764         Variable_symbol* vsym
00765             = new Variable_symbol(type, storage, init, bitsize,
00766                                   Symbol::st_Defined);
00767         add_symbol(sym_name.get_name(), vsym);
00768         sym->members.push_back(vsym);
00769         vsym->set_class(this->sym);
00770 
00771         /* if it wants to be POD, it can't contain [arrays of] pointer
00772            to member or non-POD */
00773         Type nonarr = type.sans_array();
00774         if (nonarr.get_kind() == Type::k_Member || nonarr.get_kind() == Type::k_Reference || !type.is_pod())
00775             sym->pod = false;
00776 
00777         return 0;
00778     }
00779 }
00780 
00781 #line 839 "class.cpp"
00782 
00783 static bool
00784 is_covariant_or_same(Type n, Type o)
00785 {
00786     if (n == o)
00787         return true;
00788     /* Return types are covariant if...
00789        - both are pointers or references to classes... */
00790     if ((n.get_kind() == Type::k_Pointer || n.get_kind() == Type::k_Reference)
00791         && o.get_kind() == n.get_kind()
00792         && n.get_basis_type().is_class_type() && o.get_basis_type().is_class_type())
00793     {
00794         Class_symbol* nc = downcast<Class_symbol*>(n.get_basis_type().get_type_symbol());
00795         Class_symbol* oc = downcast<Class_symbol*>(o.get_basis_type().get_type_symbol());
00796         /* - the class in B::f (oc) is the same class or an unambiguous
00797              direct or indirect base class of the class in D::f (nc)
00798            - same cv-qualification
00799            - class in D::f (nc) has same or less cv-qualification then
00800              B::f (oc) */
00801         return (nc == oc || oc->is_unique_base_class_of(nc))
00802             && n.is_same_qualified_as(o)
00803             && !n.get_basis_type().is_more_qualified_than(o.get_basis_type());
00804     }
00805     return false;
00806 }
00807 
00808 #line 864 "class.cpp"
00809 
00810 Function_signature*
00811 Class_scope::add_function_decl(Storage_class_specifier storage,
00812                                Function_specifier_set fspec,
00813                                Type type,
00814                                const Symbol_name& sym_name)
00815 {
00816     if (sym_name.is_qualified())
00817         compile_error("invalid name for member function");
00818     if (sym_name.is_template())
00819         compile_error("definition of template specialisation");
00820 
00821     Function_symbol* fsym;
00822     Symbol_pair pair = lookup_here(sym_name.get_name(), true);
00823     if (!pair || pair.tag == pair.untag) {
00824         fsym = new Function_symbol(this, sym_name.get_kind());
00825         add_symbol(sym_name.get_name(), fsym);
00826         sym->member_functions.push_back(fsym);
00827     } else {
00828         fsym = dynamic_cast<Function_symbol*>(pair.untag);
00829         if (!fsym)
00830             compile_error("`" + sym_name.get_name() + "' is not a function");
00831     }
00832 
00833     if (storage == s_None)
00834         storage = s_Member;
00835     else if (storage == s_Static)
00836         /* ok */ ;
00837     else
00838         compile_error("invalid storage class for member function");
00839 
00840     /* make function virtual if a base class already contains such a
00841        function */
00842     Class_symbol::bases_t all_your_base;
00843     sym->enumerate_base_classes(true, &all_your_base);
00844     for (Class_symbol::bases_t::iterator i = all_your_base.begin(); i != all_your_base.end(); ++i) {
00845         Function_symbol* fsym = dynamic_cast<Function_symbol*>((*i)->lookup_helper(sym_name.get_name()).untag);
00846         if (!fsym)
00847             continue;
00848         for (Function_symbol::Sig_it si = fsym->sig_begin(); si != fsym->sig_end(); ++si) {
00849             if ((*si)->is_declared() && (*si)->get_storage_specifier() == s_Member
00850                 && (*si)->get_proto_type().get_function_signature() == type.get_function_signature()
00851                 && ((*si)->get_function_specifiers() & f_Virtual))
00852             {
00853                 /* okay, it's there. Valid? */
00854                 fspec |= f_Virtual;
00855                 if (!is_covariant_or_same(type.get_return_type(), (*si)->get_return_type()))
00856                     compile_error("overriding virtual function `" + (*si)->get_function()->get_name()
00857                                   + "' with conflicting return type");
00858             }
00859         }
00860     }
00861     if ((fspec & f_Virtual) && storage != s_Member)
00862         compile_error("non-member function can't be virtual");
00863 
00864     Function_signature* sig =
00865         fsym->add_signature(type, sym->get_type(), storage, fspec,
00866                             Function_symbol::must_be_new);
00867     assert(!sig->is_declared());
00868     sig->set_status(Symbol::st_Declared);
00869 
00870     if (fspec & f_Virtual)
00871         sym->pod = false;
00872 
00873     return sig;
00874 }
00875 
00876 #line 930 "class.cpp"
00877 
00878 void
00879 Class_scope::add_function_implementation(Function_signature* fsig,
00880                                          Block_scope* scope,
00881                                          Ptree* tree,
00882                                          Ptree* initializer)
00883 {
00884     /* functions declared inside a class are automatically inline */
00885     fsig->merge_fspec(f_Inline);
00886 
00887     /* enqueue function body for later processing */
00888     get_parent()->add_function_implementation(fsig, scope, tree, initializer);
00889 }
00890 
00891 #line 943 "class.cpp"
00892 
00893 bool
00894 Class_scope::is_constructor(Ptree* tree)
00895 {
00896     // FIXME: in template classes, "name <THINGS>" may also a constructor
00897     return tree->IsLeaf() && tree->ToString() == sym->get_real_name();
00898 }

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