diff options
Diffstat (limited to 'libbuild2/function.cxx')
-rw-r--r-- | libbuild2/function.cxx | 124 |
1 files changed, 62 insertions, 62 deletions
diff --git a/libbuild2/function.cxx b/libbuild2/function.cxx index 25dacf9..3110547 100644 --- a/libbuild2/function.cxx +++ b/libbuild2/function.cxx @@ -80,21 +80,6 @@ namespace build2 return i != map_.end () && i->first.compare (0, n, name) == 0; } - auto function_map:: - insert (string name, function_overload f) -> iterator - { - // Sanity checks. - // - assert (f.arg_min <= f.arg_max && - f.arg_types.size () <= f.arg_max && - f.impl != nullptr); - - auto i (map_.emplace (move (name), move (f))); - - i->second.name = i->first.c_str (); - return i; - } - pair<value, bool> function_map:: call (const scope* base, const string& name, @@ -120,16 +105,17 @@ namespace build2 // See the overall function machinery description for the ranking // semantics. // - auto ip (map_.equal_range (name)); + const function_overloads* all_ovls (find (name)); size_t rank (~0); small_vector<const function_overload*, 2> ovls; + if (all_ovls != nullptr) { size_t count (args.size ()); - for (auto it (ip.first); it != ip.second; ++it) + for (auto it (all_ovls->begin ()); it != all_ovls->end (); ++it) { - const function_overload& f (it->second); + const function_overload& f (*it); // Argument count match. // @@ -227,7 +213,7 @@ namespace build2 if (f->arg_types[i] && *f->arg_types[i] == nullptr && args[i].type != nullptr) - untypify (args[i]); + untypify (args[i], true /* reduce */); } } @@ -257,8 +243,11 @@ namespace build2 dr << fail (loc) << "unmatched call to "; print_call (dr.os); - for (auto i (ip.first); i != ip.second; ++i) - dr << info << "candidate: " << i->second; + if (all_ovls != nullptr) + { + for (auto i (all_ovls->begin ()); i != all_ovls->end (); ++i) + dr << info << "candidate: " << *i; + } // If this is an unqualified name, then also print qualified // functions that end with this name. But skip functions that we @@ -271,14 +260,20 @@ namespace build2 for (auto i (begin ()); i != end (); ++i) { const string& q (i->first); - const function_overload& f (i->second); - if ((f.alt_name == nullptr || f.alt_name != name) && - q.size () > n) + if (q.size () > n) { - size_t p (q.size () - n); - if (q[p - 1] == '.' && q.compare (p, n, name) == 0) - dr << info << "candidate: " << i->second; + for (auto j (i->second.begin ()); j != i->second.end (); ++j) + { + const function_overload& f (*j); + + if (f.alt_name == nullptr || f.alt_name != name) + { + size_t p (q.size () - n); + if (q[p - 1] == '.' && q.compare (p, n, name) == 0) + dr << info << "candidate: " << f; + } + } } } } @@ -300,30 +295,8 @@ namespace build2 } } - value function_family:: - default_thunk (const scope* base, - vector_view<value> args, - const function_overload& f) - { - // Call the cast thunk. - // - struct cast_data // Prefix of function_cast::data. - { - value (*const thunk) (const scope*, vector_view<value>, const void*); - }; - - auto d (reinterpret_cast<const cast_data*> (&f.data)); - return d->thunk (base, move (args), d); - } - -#if !defined(_WIN32) - constexpr const optional<const value_type*>* function_args<>::types; -#else - const optional<const value_type*>* const function_args<>::types = nullptr; -#endif - - void function_family::entry:: - insert (string n, function_overload f) const + auto function_family:: + insert (string n, bool pure) const -> entry { // Figure out qualification. // @@ -332,56 +305,83 @@ namespace build2 if (p == string::npos) { - if (!qual.empty ()) + if (!qual_.empty ()) { - qn = qual; + qn = qual_; qn += '.'; qn += n; } } else if (p == 0) { - assert (!qual.empty ()); - n.insert (0, qual); + assert (!qual_.empty ()); + n.insert (0, qual_); } - auto i (qn.empty () ? map_.end () : map_.insert (move (qn), f)); - auto j (map_.insert (move (n), move (f))); + return entry { + map_.insert (move (n), pure), + qn.empty () ? nullptr : &map_.insert (move (qn), pure), + thunk_}; + } - // If we have both, then set alternative names. + value function_family:: + default_thunk (const scope* base, + vector_view<value> args, + const function_overload& f) + { + // Call the cast thunk. // - if (i != map_.end ()) + struct cast_data // Prefix of function_cast::data. { - i->second.alt_name = j->first.c_str (); - j->second.alt_name = i->first.c_str (); - } + value (*const thunk) (const scope*, vector_view<value>, const void*); + }; + + auto d (reinterpret_cast<const cast_data*> (&f.data)); + return d->thunk (base, move (args), d); } +#if !defined(_WIN32) + constexpr const optional<const value_type*>* function_args<>::types; +#else + const optional<const value_type*>* const function_args<>::types = nullptr; +#endif + // Static-initialize the function map and populate with builtin functions. // + // NOTE: remember to also arrange for automatic documentation extraction in + // doc/buildfile! + void bool_functions (function_map&); // functions-bool.cxx void builtin_functions (function_map&); // functions-builtin.cxx void filesystem_functions (function_map&); // functions-filesystem.cxx + void integer_functions (function_map&); // functions-integer.cxx + void json_functions (function_map&); // functions-json.cxx void name_functions (function_map&); // functions-name.cxx void path_functions (function_map&); // functions-path.cxx void process_functions (function_map&); // functions-process.cxx void process_path_functions (function_map&); // functions-process-path.cxx void regex_functions (function_map&); // functions-regex.cxx void string_functions (function_map&); // functions-string.cxx + void target_functions (function_map&); // functions-target.cxx void target_triplet_functions (function_map&); // functions-target-triplet.cxx void project_name_functions (function_map&); // functions-target-triplet.cxx + void insert_builtin_functions (function_map& m) { + bool_functions (m); builtin_functions (m); filesystem_functions (m); + integer_functions (m); + json_functions (m); name_functions (m); path_functions (m); process_functions (m); process_path_functions (m); regex_functions (m); string_functions (m); + target_functions (m); target_triplet_functions (m); project_name_functions (m); } |