Decl& specialize_function(Context& cxt, Template_decl& tmp, Function_decl& d, Substitution& sub) { #if 0 // Create the specialization name. Name& n = cxt.get_template_id(tmp, sub.arguments()); // Substitute through parameters. // // TODO: I think I need to re-establish name bindings during substitution // because we are going to be resolving types at the same time. This // means that I am going to have to move scoping facilities from the // parser to the context (which makes some sense). Decl_list parms; for (Decl& p1 : d.parameters()) { Decl& p2 = substitute(cxt, p1, sub); parms.push_back(p2); } // Substitute through the return type. Type& ret = substitute(cxt, d.return_type(), sub); // FIXME: I've just re-attached an uninstantiated definition // to the declaration. That is going to be a problem. // return cxt.make_function_declaration(n, parms, ret, d.definition()); #endif lingo_unreachable(); }
// Perform qualified lookup to resolve the declaration referred to by obj.n. Expr& make_member_reference(Context& cxt, Expr& obj, Simple_id& name) { Type& type = obj.type(); Decl_list decls = qualified_lookup(cxt, type, name); if (decls.size() == 1) return make_member_reference(cxt, obj, decls.front()); lingo_unreachable(); }
// Perform unqualified lookup. // // TODO: Allow an lookup to fail, indicating that we could not find // a name. In function calls, this could be used to perform class // lookup for member functions. Expr& make_reference(Context& cxt, Simple_id& id) { Decl_list decls = unqualified_lookup(cxt, id); if (decls.size() == 1) return make_decl_ref(cxt, decls.front()); else return make_ovl_ref(cxt, id, std::move(decls)); }
// Parse a template parameter list. // // template-parameter-list: // template-parameter // template-parameter-list ',' template-parameter Decl_list Parser::template_parameter_list() { Decl_list ds; do { Decl& d = template_parameter(); ds.push_back(d); } while (match_if(tk::comma_tok)); return ds; }
// Perform unqualified lookup. Expr& make_reference(Context& cxt, Simple_id& id) { Decl_list decls = unqualified_lookup(cxt, id); if (decls.size() == 1) return make_reference(cxt, decls.front()); // TODO: Return a reference to an overload set. banjo_unhandled_case(id); }
// Perform qualified lookup to resolve the declaration referred to by obj.n. // // TODO: Allow class lookup to find static Expr& make_member_ref(Context& cxt, Expr& obj, Simple_id& name) { Type& type = obj.type(); Decl_list decls = qualified_lookup(cxt, type, name); if (decls.size() == 1) return make_member_decl_ref(cxt, obj, decls.front()); else return make_member_ovl_ref(cxt, obj, name, std::move(decls)); }
// Initialize the substitution with a mapping from each // `pi` in `p` to its corresponding `ai` in `a`. inline Substitution::Substitution(Decl_list& p, Term_list& a) { auto pi = p.begin(); auto ai = a.begin(); while (pi != p.end()) { send(*pi, *ai); ++pi; ++ai; } }
// Perform qualified lookup to resolve the declaration referred to by obj.n. // // FIXME: This needs to perform class lookup, not qualified lookup. static Expr& make_member_ref(Context& cxt, Expr& obj, Simple_id& name) { Type& type = obj.type(); Decl_list decls = qualified_lookup(cxt, type, name); if (decls.empty()) { error(cxt, "no matching declaration for '{}'", name); throw Lookup_error(); } if (decls.size() == 1) return make_resolved_mem_ref(cxt, obj, decls.front()); else return make_mem_overload_ref(cxt, obj, name, std::move(decls)); }
// Synthesize a list of template arguments from a list of // template parameter list. Term_list synthesize_template_arguments(Context& cxt, Decl_list& parms) { Term_list args; args.reserve(parms.size()); for (Decl& p : parms) { Term& arg = synthesize_template_argument(cxt, p); args.push_back(arg); } return args; }
// Return a list of converted template arguments. Term_list initialize_template_parameters(Context& cxt, Decl_list& parms, Term_list& args) { // TODO: Handle default arguments here. if (args.size() < parms.size()) throw std::runtime_error("too few template arguments"); // Build a list of converted template arguments by initializing // each parameter in turn. Term_list ret; Decl_iter p0 = parms.begin(), pi = p0, pn = parms.end(); Term_iter a0 = args.begin(), ai = a0, an = args.end(); while (pi != pn && ai != an) { Term& e = initialize_template_parameter(cxt, p0, pi, a0, ai); // TODO: If pi is a pack, then we want to merge e into // a single pack argument so that so that the number of // parameters and arguments conform. ret.push_back(e); } return ret; }