diff options
Diffstat (limited to 'libbuild2/target.ixx')
-rw-r--r-- | libbuild2/target.ixx | 83 |
1 files changed, 58 insertions, 25 deletions
diff --git a/libbuild2/target.ixx b/libbuild2/target.ixx index 39b81e7..1dc667d 100644 --- a/libbuild2/target.ixx +++ b/libbuild2/target.ixx @@ -207,7 +207,7 @@ namespace build2 { return prerequisites_state_.load (memory_order_acquire) == 2 ? prerequisites_ - : empty_prerequisites_; + : empty_prerequisites; } inline bool target:: @@ -286,6 +286,7 @@ namespace build2 // @@ Hm, I wonder why not just return s.recipe_group_action now that we // cache it. // + const opstate& s (state[a]); // This special hack allows us to do things like query an ad hoc member's // state or mtime without matching/executing the member, only the group. @@ -294,12 +295,15 @@ namespace build2 // execute phase). // // Note: this test must come first since the member may not be matched and - // thus its state uninitialized. + // thus its state set (but it won't be postponed; see opstate::state). // if (ctx.phase == run_phase::execute && adhoc_group_member ()) - return true; - - const opstate& s (state[a]); + { + // Note: if the member state is postponed, then the group state may not + // be yet known (see group_action() for details). + // + return s.state != target_state::postponed; + } if (s.state == target_state::group) return true; @@ -342,7 +346,14 @@ namespace build2 inline target_state target:: executed_state_impl (action a) const { - return (group_state (a) ? group->state : state)[a].state; + target_state ts ((group_state (a) ? group->state : state)[a].state); + + // Translate postponed to unchanged, similar to execute_recipe(). + // + if (ts == target_state::postponed) + ts = target_state::unchanged; + + return ts; } inline target_state target:: @@ -480,42 +491,64 @@ namespace build2 // inline group_prerequisites:: group_prerequisites (const target& t) - : t_ (t), - g_ (t_.group == nullptr || - t_.group->adhoc_member != nullptr || // Ad hoc group member. - t_.group->prerequisites ().empty () - ? nullptr : t_.group) + : t_ (nullptr), g_ (nullptr) { + // Take "snapshot" of prerequisites, both for target and group. + // + const auto& ps (t.prerequisites ()); + if (!ps.empty ()) + t_ = &ps; + + if (const target* g = t.group) + { + if (g->adhoc_member == nullptr) // Not ad hoc group member. + { + const auto& ps (g->prerequisites ()); + if (!ps.empty ()) + g_ = &ps; + } + } } inline group_prerequisites:: group_prerequisites (const target& t, const target* g) - : t_ (t), - g_ (g == nullptr || - g->prerequisites ().empty () - ? nullptr : g) + : t_ (nullptr), g_ (nullptr) { + const auto& ps (t.prerequisites ()); + if (!ps.empty ()) + t_ = &ps; + + if (g != nullptr) + { + const auto& ps (g->prerequisites ()); + if (!ps.empty ()) + g_ = &ps; + } } inline auto group_prerequisites:: begin () const -> iterator { - auto& c ((g_ != nullptr ? *g_ : t_).prerequisites ()); - return iterator (&t_, g_, &c, c.begin ()); + auto* c (g_ != nullptr ? g_ : + t_ != nullptr ? t_ : + &empty_prerequisites); + return iterator (t_, g_, c, c->begin ()); } inline auto group_prerequisites:: end () const -> iterator { - auto& c (t_.prerequisites ()); - return iterator (&t_, g_, &c, c.end ()); + auto* c (t_ != nullptr ? t_ : + g_ != nullptr ? g_ : + &empty_prerequisites); + return iterator (t_, g_, c, c->end ()); } inline size_t group_prerequisites:: size () const { - return t_.prerequisites ().size () + - (g_ != nullptr ? g_->prerequisites ().size () : 0); + return ((t_ != nullptr ? t_->size () : 0) + + (g_ != nullptr ? g_->size () : 0)); } // group_prerequisites::iterator @@ -523,9 +556,9 @@ namespace build2 inline auto group_prerequisites::iterator:: operator++ () -> iterator& { - if (++i_ == c_->end () && c_ != &t_->prerequisites ()) + if (++i_ == c_->end () && c_ == g_ && t_ != nullptr) { - c_ = &t_->prerequisites (); + c_ = t_; i_ = c_->begin (); } return *this; @@ -535,9 +568,9 @@ namespace build2 inline auto group_prerequisites::iterator:: operator-- () -> iterator& { - if (i_ == c_->begin () && c_ == &t_->prerequisites ()) + if (i_ == c_->begin () && c_ == t_) { - c_ = &g_->prerequisites (); + c_ = g_; i_ = c_->end (); } |