From b8d4cb75ca4f6214a0cac22c96691e770d5940d9 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 15 Sep 2021 10:25:15 +0200 Subject: Do variable lookup in ad hoc target groups --- libbuild2/scope.cxx | 33 +++++++++++++++++++++++++-------- libbuild2/scope.hxx | 3 ++- libbuild2/target.cxx | 29 +++++++++++++++++++---------- libbuild2/target.hxx | 9 ++++++--- 4 files changed, 52 insertions(+), 22 deletions(-) diff --git a/libbuild2/scope.cxx b/libbuild2/scope.cxx index 39aba8f..93f21db 100644 --- a/libbuild2/scope.cxx +++ b/libbuild2/scope.cxx @@ -46,10 +46,12 @@ namespace build2 pair scope:: lookup_original (const variable& var, const target_key* tk, - const target_key* gk, + const target_key* g1k, + const target_key* g2k, size_t start_d) const { assert (tk != nullptr || var.visibility != variable_visibility::target); + assert (g2k == nullptr || g1k != nullptr); size_t d (0); @@ -61,7 +63,8 @@ namespace build2 auto pre_app = [&var, this] (lookup_type& l, const scope* s, const target_key* tk, - const target_key* gk, + const target_key* g1k, + const target_key* g2k, string n) { const value& v (*l); @@ -76,7 +79,7 @@ namespace build2 // group, then we shouldn't be looking for stem in the target's // variables. In other words, once we "jump" to group, we stay there. // - lookup_type stem (s->lookup_original (var, tk, gk, 2).first); + lookup_type stem (s->lookup_original (var, tk, g1k, g2k, 2).first); // Check the cache. // @@ -140,7 +143,8 @@ namespace build2 // the copy. // optional tn; - optional gn; + optional g1n; + optional g2n; for (const scope* s (this); s != nullptr; ) { @@ -159,7 +163,7 @@ namespace build2 if (l.defined ()) { if (l->extra != 0) // Prepend/append? - pre_app (l, s, tk, gk, move (*tn)); + pre_app (l, s, tk, g1k, g2k, move (*tn)); return make_pair (move (l), d); } @@ -170,17 +174,30 @@ namespace build2 // if (++d >= start_d) { - if (f && gk != nullptr) + if (f && g1k != nullptr) { - lookup_type l (s->target_vars.find (*gk, var, gn)); + lookup_type l (s->target_vars.find (*g1k, var, g1n)); if (l.defined ()) { if (l->extra != 0) // Prepend/append? - pre_app (l, s, gk, nullptr, move (*gn)); + pre_app (l, s, g1k, g2k, nullptr, move (*g1n)); return make_pair (move (l), d); } + + if (g2k != nullptr) + { + l = s->target_vars.find (*g2k, var, g2n); + + if (l.defined ()) + { + if (l->extra != 0) // Prepend/append? + pre_app (l, s, g2k, nullptr, nullptr, move (*g2n)); + + return make_pair (move (l), d); + } + } } } } diff --git a/libbuild2/scope.hxx b/libbuild2/scope.hxx index b83f699..97c7be5 100644 --- a/libbuild2/scope.hxx +++ b/libbuild2/scope.hxx @@ -181,7 +181,8 @@ namespace build2 pair lookup_original (const variable&, const target_key* tk = nullptr, - const target_key* gk = nullptr, + const target_key* g1k = nullptr, + const target_key* g2k = nullptr, size_t start_depth = 1) const; pair diff --git a/libbuild2/target.cxx b/libbuild2/target.cxx index 24ad01e..7db5c66 100644 --- a/libbuild2/target.cxx +++ b/libbuild2/target.cxx @@ -159,22 +159,29 @@ namespace build2 r.first = lookup_type (*p.first, p.second, vars); } - const target* g (nullptr); + const target* g1 (nullptr); + const target* g2 (nullptr); if (!r.first) { ++r.second; - // Skip looking up in the ad hoc group, which is semantically the - // first/primary member. + // In case of an ad hoc group, we may have to look in two groups. // - if ((g = group == nullptr - ? nullptr - : group->adhoc_group () ? group->group : group)) + if ((g1 = group) != nullptr) { - auto p (g->vars.lookup (var)); + auto p (g1->vars.lookup (var)); if (p.first != nullptr) - r.first = lookup_type (*p.first, p.second, g->vars); + r.first = lookup_type (*p.first, p.second, g1->vars); + else + { + if ((g2 = g1->group) != nullptr) + { + auto p (g2->vars.lookup (var)); + if (p.first != nullptr) + r.first = lookup_type (*p.first, p.second, g2->vars); + } + } } } @@ -185,14 +192,16 @@ namespace build2 if (!target_only) { target_key tk (key ()); - target_key gk (g != nullptr ? g->key () : target_key {}); + target_key g1k (g1 != nullptr ? g1->key () : target_key {}); + target_key g2k (g2 != nullptr ? g2->key () : target_key {}); if (bs == nullptr) bs = &base_scope (); auto p (bs->lookup_original (var, &tk, - g != nullptr ? &gk : nullptr)); + g1 != nullptr ? &g1k : nullptr, + g2 != nullptr ? &g2k : nullptr)); r.first = move (p.first); r.second = r.first ? r.second + p.second : p.second; diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx index 21b5dab..8193f35 100644 --- a/libbuild2/target.hxx +++ b/libbuild2/target.hxx @@ -266,9 +266,6 @@ namespace build2 // - Ad hoc group cannot have sub-groups (of any kind) though an ad hoc // group can be a sub-group of an explicit group. // - // - Member variable lookup skips the ad hoc group (since the group is the - // first member, this is normally what we want). - // // Note that ad hoc groups can be part of explicit groups. In a sense, we // have a two-level grouping: an explicit group with its members each of // which can be an ad hoc group. For example, lib{} contains libs{} which @@ -279,6 +276,9 @@ namespace build2 // const_ptr adhoc_member = nullptr; + // Return true if this target is an ad hoc group (that is, its primary + // member). + // bool adhoc_group () const { @@ -288,6 +288,9 @@ namespace build2 (group == nullptr || group->adhoc_member == nullptr); } + // Return true if this target is an ad hoc group member (that is, its + // secondary member). + // bool adhoc_group_member () const { -- cgit v1.1