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

function.cc

Go to the documentation of this file.
00001 // AUTOMATICALLY GENERATED -- DO NOT EDIT!         -*- c++ -*-
00002 
00003 #include "function.h"
00004 #include "function_i.h"
00005 
00006 
00007 #line 69 "function.cpp"
00008 
00009 /**************************** Function_symbol ****************************/
00010 
00011 
00012 Function_symbol::Function_symbol(Abstract_scope* declared_scope,
00013                                  Symbol_name::Kind fun_kind)
00014     : declared_scope(declared_scope), fun_kind(fun_kind)
00015 {
00016     /* avoid the wording "undefined function" in dumps. A function
00017        signature is not an object. */
00018     set_status(st_Defined);
00019 }
00020 
00021 #line 87 "function.cpp"
00022 
00023 Function_symbol::Kind
00024 Function_symbol::get_kind() const
00025 {
00026     return k_Function;
00027 }
00028 
00029 #line 93 "function.cpp"
00030 
00031 void
00032 Function_symbol::fill_in_mangled_names(bool ignore_if_one)
00033 {
00034     if (ignore_if_one && signatures.size() == 1) {
00035         if (signatures.front()->get_name().length() == 0)
00036             signatures.front()->set_name(get_name(), get_basename().length());
00037         return;
00038     }
00039     for (Sig_it i = signatures.begin(); i != signatures.end(); ++i) {
00040         if ((*i)->get_name().length() == 0) {
00041             std::string s = Symbol_name::get_mangled_function_name(get_basename(),
00042                                                                    (*i)->get_proto_type(),
00043                                                                    (*i)->get_this_type());
00044             (*i)->set_name(declared_scope->get_unique_name(s), s.length());
00045         }
00046     }
00047 }
00048 
00049 #line 111 "function.cpp"
00050 
00061 Function_signature*
00062 Function_symbol::add_signature(Type t, Type this_type,
00063                                Storage_class_specifier sc,
00064                                Function_specifier_set f,
00065                                Add_arg what_to_do)
00066 {
00067     assert(sc == s_Extern || sc == s_Static || sc == s_Member || sc == s_None);
00068 
00069     /* qualifiers of t actually apply to this_type, i.e.
00070        `void(int) const' in `Foo' actually is `void(int)' in `const Foo' */
00071     if (this_type.is_valid()) {
00072         if (t.is_qualified(Type::q_Restrict))
00073             compile_error("restrict not allowed as function type qualifier");
00074         this_type.copy_qualifiers(t);
00075         t = t.get_unqualified_type();
00076     } else {
00077         if (t.is_qualified())
00078             compile_error("non-member function can't be qualified");
00079     }
00080 
00081     /* look up function signature */
00082     std::string tsig = t.get_function_signature();
00083     Function_signature* found_sig = 0;
00084 
00085     for (Sig_vec::iterator i = signatures.begin(); i != signatures.end(); ++i) {
00086         Function_signature* sig = *i;
00087         if (sig->get_proto_type().get_function_signature() == tsig)
00088             if (!found_sig || sig->get_this_type() == this_type)
00089                 found_sig = sig;
00090     }
00091 
00092     if (found_sig) {
00093         /* we already have a function which takes the same parameters */
00094         if (found_sig->get_storage_specifier() == s_Member) {
00095             /* the existing function is a member. This one must
00096                be a member, too; maybe with different this_type. */
00097             if (sc != s_None && sc != s_Member)
00098                 compile_error("new static function collides with existing member");
00099             assert(this_type.is_valid());
00100             if (this_type == found_sig->get_this_type()) {
00101                 if (what_to_do == must_be_new)
00102                     compile_error("function already declared");
00103                 found_sig->merge_fspec(f);
00104                 return found_sig;
00105             }
00106             /* fallthrough to creation of new signature */
00107         } else {
00108             /* the existing function is not a member. this_type is
00109                irrelevant */
00110             if (this_type.is_valid() && this_type.is_qualified())
00111                 compile_error("static functions may not be qualified");
00112             if (sc == s_Member)
00113                 compile_error("new member function collides with existing static function");
00114             if (what_to_do == must_be_new)
00115                 compile_error("function already declared");
00116             found_sig->merge_fspec(f);
00117             return found_sig;
00118         }
00119     }
00120 
00121     if (what_to_do == must_be_declared)
00122         compile_error("can't introduce new signatures here");
00123 
00124     /* okay, it's a new function */
00125     Type call_type;
00126     if (sc == s_None)
00127         sc = s_Extern;
00128 
00129     if (sc != s_Member) {
00130         // FIXME: check function kind?
00131         this_type = Type();
00132         call_type = t;
00133     } else {
00134         if (get_function_kind() == Symbol_name::k_Constructor) {
00135             // FIXME: HACK HACK HACK. Replace the return type.
00136             std::string s = t.get_encoded_type();
00137             s.erase(s.length()-1);
00138             call_type = Type(s);
00139         } else if (get_function_kind() == Symbol_name::k_Destructor) {
00140             call_type = make_unary_function_type(this_type.make_reference_type(),
00141                                                  void_type);
00142         } else if (get_function_kind() == Symbol_name::k_Conversion) {
00143             call_type = make_unary_function_type(this_type.make_reference_type(),
00144                                                  t.get_return_type());
00145         } else {
00146             call_type = t.with_first_arg(this_type.make_reference_type());
00147         }
00148     }
00149 
00150     Function_signature* sig = new Function_signature(t, this_type,
00151                                                      call_type,
00152                                                      sc, f, this);
00153 
00154     signatures.push_back(sig);
00155     return sig;
00156 }
00157 
00158 #line 218 "function.cpp"
00159 
00161 bool
00162 Function_symbol::is_overloaded() const
00163 {
00164     /* only count declared functions:
00165          void foo() {
00166             extern void foo(int);
00167          }
00168          void bar() {
00169             foo;           // foo is not an overloaded function here
00170          }                 // although we know the second signature
00171     */
00172     Sig_vec::size_type n = 0;
00173     for (Sig_vec::const_iterator i = signatures.begin(); i != signatures.end(); ++i)
00174         if ((*i)->is_declared())
00175             ++n;
00176     return n != 1;
00177 }
00178 
00179 #line 244 "function.cpp"
00180 
00183 Function_signature*
00184 Function_symbol::get_nonoverloaded_signature() const
00185 {
00186     assert(!is_overloaded());
00187     for (Sig_vec::const_iterator i = signatures.begin(); i != signatures.end(); ++i)
00188         if ((*i)->is_declared())
00189             return *i;
00190     assert(0);
00191 }
00192 
00193 #line 256 "function.cpp"
00194 
00200 Function_signature*
00201 Function_symbol::get_function_signature(Type type, bool* ambig) const
00202 {
00203     assert(type.get_kind() == Type::k_Pointer || type.get_kind() == Type::k_Member);
00204     Function_signature* p = 0;
00205     for (Sig_vec::const_iterator i = signatures.begin(); i != signatures.end(); ++i) {
00206         if ((*i)->is_declared() && (*i)->has_pointer_type(type)) {
00207             if (p) {
00208                 if (ambig)
00209                     *ambig = true;
00210                 return 0;       // ambiguous
00211             } else {
00212                 p = *i;
00213             }
00214         }
00215     }
00216     if (ambig)
00217         *ambig = false;
00218     return p;
00219 }
00220 
00221 #line 282 "function.cpp"
00222 
00223 void
00224 Function_symbol::dump(std::ostream& os)
00225 {
00226     Symbol::dump(os);
00227     for (Sig_vec::iterator i = signatures.begin(); i != signatures.end(); ++i) {
00228         os << "\n  " << (*i)->get_name() << ":\n  ";
00229         (*i)->dump(os);
00230     }
00231 }
00232 
00233 #line 292 "function.cpp"
00234 
00235 /*************************** Function_signature **************************/
00236 
00245 Function_signature::Function_signature(Type t, Type this_type,
00246                                        Type call_type,
00247                                        Storage_class_specifier sc,
00248                                        Function_specifier_set f,
00249                                        Function_symbol* backlink)
00250     : proto_type(t), this_type(this_type),
00251       call_type(call_type),
00252       storage_spec(sc), function_spec(f),
00253       builtin(false), generated(false), backlink(backlink), definition(0)
00254 {
00255     assert(this_type.is_valid() == (sc == s_Member));
00256 }
00257 
00258 #line 315 "function.cpp"
00259 
00263 Function_signature*
00264 Function_signature::make_builtin(Type t)
00265 {
00266     Function_signature* fsig = new Function_signature(t, Type(), t, s_Extern, f_None, 0);
00267     fsig->set_name("builtin", 7);
00268     fsig->set_builtin();
00269     return fsig;
00270 }
00271 
00272 #line 327 "function.cpp"
00273 
00275 Type
00276 Function_signature::get_return_type() const
00277 {
00278     return get_proto_type().get_return_type();
00279 }
00280 
00281 #line 356 "function.cpp"
00282 
00288 bool
00289 Function_signature::has_pointer_type(Type t) const
00290 {
00291     if (this_type.is_valid()) {
00292         /* this is a member function */
00293         assert(storage_spec == s_Member);
00294         /* target must be pointer to member */
00295         if (t.get_kind() != Type::k_Member || t.get_member_type().get_kind() != Type::k_Function)
00296             return false;
00297         /* signature must fit */
00298         if (t.get_member_type() != proto_type)
00299             return false;
00300         /* qualifications on class type must fit:
00301            "void (c::*pmf)() = &c::const_mf" works,
00302            "void (c::*pmf)() const = &c::nonconst_mf" doesn't */
00303         Type cl = t.get_class_type();
00304         if (cl.is_more_qualified_than(this_type))
00305             return false;
00306         /* derivation:
00307            "void (derived::*pmf)() = &base::mf" */
00308         return cl.get_unqualified_type() == this_type.get_unqualified_type()
00309             || downcast<Class_symbol*>(this_type.get_type_symbol())->is_unique_base_class_of(downcast<Class_symbol*>(cl.get_type_symbol()));
00310     } else {
00311         /* this is a static function */
00312         if (t.get_kind() != Type::k_Pointer)
00313             return false;
00314         return t.get_basis_type().is_same_unqualified_type(proto_type);
00315     }
00316 }
00317 
00318 #line 391 "function.cpp"
00319 
00321 Type
00322 Function_signature::get_pointer_type() const
00323 {
00324     if (this_type.is_valid()) {
00325         return this_type.make_member_type(proto_type);
00326     } else {
00327         return proto_type;
00328     }
00329 }
00330 
00331 #line 416 "function.cpp"
00332 
00334 void
00335 Function_signature::merge_fspec(Function_specifier_set fspec)
00336 {
00337     if (fspec & ~f_Inline)
00338         compile_error("only the `inline' specifier can be added to a declared function");
00339     function_spec |= fspec;
00340 }
00341 
00342 #line 483 "function.cpp"
00343 
00346 void
00347 Function_signature::set_body(Ptree* tree, Ptree* init)
00348 {
00349     set_status(st_Defined);
00350     definition = tree;
00351     initializers = init;
00352 }
00353 
00354 #line 493 "function.cpp"
00355 
00356 Function_signature::Par_vec::const_iterator
00357 Function_signature::par_begin() const
00358 {
00359     return parameters.begin();
00360 }
00361 
00362 #line 499 "function.cpp"
00363 
00364 Function_signature::Par_vec::const_iterator
00365 Function_signature::par_end() const
00366 {
00367     return parameters.end();
00368 }
00369 
00370 #line 505 "function.cpp"
00371 
00372 void
00373 Function_signature::add_parameter(Variable_symbol* vsym)
00374 {
00375     assert(vsym->get_type().is_same_unqualified_type(get_proto_type().get_function_arg(parameters.size())));
00376     parameters.push_back(vsym);
00377 }
00378 
00379 #line 512 "function.cpp"
00380 
00381 Symbol::Kind
00382 Function_signature::get_kind() const
00383 {
00384     return k_Function;
00385 }
00386 
00387 #line 518 "function.cpp"
00388 
00389 void
00390 Function_signature::dump(std::ostream& os)
00391 {
00392     Symbol::dump(os);
00393     os << ", type is `" << proto_type.get_human_readable_type()
00394        << "'\n    storage: " << get_storage_specifier_name(storage_spec)
00395        << ", function specifiers: " << get_function_specifier_name(function_spec)
00396        << ", class type: ";
00397     if (this_type.is_valid())
00398         os << "`" << this_type.get_human_readable_type() << "'";
00399     else
00400         os << "(none)";
00401     if (is_generated())
00402         os << ", synthesized";
00403     if (Symbol_table::has_dump_flag('b')) {
00404         if (initializers) {
00405             os << "\n    Member Initializers:\n";
00406             print_annotated_tree(os, "    | ", initializers, Symbol_table::has_dump_flag('c'));
00407         }
00408         if (definition) {
00409             os << "\n    Body:\n";
00410             print_annotated_tree(os, "    | ", definition, Symbol_table::has_dump_flag('c'));
00411         }
00412     }
00413 }

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