00001
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
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
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
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
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
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
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
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
00270
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
00299
00300
00301
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
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
00380
00381
00382
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
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
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
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
00417
00418
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
00425
00426 while (scope && dynamic_cast<Class_scope*>(scope))
00427 scope = scope->get_parent();
00428
00429 assert(scope);
00430 }
00431
00432 return adder.add_class(scope, sym_name.get_name(), k);
00433 }
00434 }
00435
00436
00437 Class_symbol* csym;
00438 Ptree* name = tree->Second();
00439 Ptree* body;
00440 Ptree* bases;
00441
00442
00443
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
00474 if (bases)
00475 process_base_classes(csym, bases, scope);
00476 if (body) {
00477
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
00488 csym->set_status(Symbol::st_Defined);
00489 return csym;
00490 }
00491
00492 #line 570 "class.cpp"
00493
00494
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
00541
00542
00543
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
00550 for (iter_t i = sym->base_classes.begin(); i != sym->base_classes.end(); ++i)
00551 add_class(*i);
00552
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
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
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
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
00669
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
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
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 ;
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
00754
00755
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
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
00772
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
00789
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
00797
00798
00799
00800
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 ;
00837 else
00838 compile_error("invalid storage class for member function");
00839
00840
00841
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
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
00885 fsig->merge_fspec(f_Inline);
00886
00887
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
00897 return tree->IsLeaf() && tree->ToString() == sym->get_real_name();
00898 }