aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/target.ixx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/target.ixx')
-rw-r--r--libbuild2/target.ixx83
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 ();
}