aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbuild2/cc/compile-rule.cxx28
-rw-r--r--libbuild2/target-type.hxx15
2 files changed, 37 insertions, 6 deletions
diff --git a/libbuild2/cc/compile-rule.cxx b/libbuild2/cc/compile-rule.cxx
index 62391f3..6258ce8 100644
--- a/libbuild2/cc/compile-rule.cxx
+++ b/libbuild2/cc/compile-rule.cxx
@@ -1551,12 +1551,12 @@ namespace build2
// Reverse-lookup target type(s) from extension.
//
small_vector<const target_type*, 2> compile_rule::
- map_extension (const scope& s, const string& n, const string& e) const
+ map_extension (const scope& bs, const string& n, const string& e) const
{
// We will just have to try all of the possible ones, in the "most
// likely to match" order.
//
- auto test = [&s, &n, &e] (const target_type& tt) -> bool
+ auto test = [&bs, &n, &e] (const target_type& tt) -> bool
{
// Call the extension derivation function. Here we know that it will
// only use the target type and name from the target key so we can
@@ -1566,7 +1566,7 @@ namespace build2
// This is like prerequisite search.
//
- optional<string> de (tt.default_extension (tk, s, nullptr, true));
+ optional<string> de (tt.default_extension (tk, bs, nullptr, true));
return de && *de == e;
};
@@ -1577,6 +1577,28 @@ namespace build2
if (test (**p))
r.push_back (*p);
+ // Next try target types derived from any of the C-source types.
+ //
+ const target_type_map& ttm (bs.root_scope ()->root_extra->target_types);
+
+ for (auto i (ttm.type_begin ()), e (ttm.type_end ()); i != e; ++i)
+ {
+ const target_type& dt (i->second);
+
+ for (const target_type* const* p (x_inc); *p != nullptr; ++p)
+ {
+ const target_type& bt (**p);
+
+ if (dt.is_a (bt))
+ {
+ if (dt != bt && test (dt))
+ r.push_back (&dt);
+
+ break;
+ }
+ }
+ }
+
return r;
}
diff --git a/libbuild2/target-type.hxx b/libbuild2/target-type.hxx
index 5798766..0e24e3a 100644
--- a/libbuild2/target-type.hxx
+++ b/libbuild2/target-type.hxx
@@ -189,7 +189,7 @@ namespace build2
file_map_.emplace (n, tt);
}
- private:
+ public:
struct target_type_ref
{
// Like reference_wrapper except it sometimes deletes the target type.
@@ -214,8 +214,17 @@ namespace build2
bool d_;
};
- map<string, target_type_ref> type_map_;
- map<string, reference_wrapper<const target_type>> file_map_;
+ using type_map = map<string, target_type_ref>;
+ using file_map = map<string, reference_wrapper<const target_type>>;
+
+ using type_iterator = type_map::const_iterator;
+
+ type_iterator type_begin () const {return type_map_.begin ();}
+ type_iterator type_end () const {return type_map_.end ();}
+
+ private:
+ type_map type_map_;
+ file_map file_map_;
};
}