aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2024-07-29 10:44:18 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2024-07-29 10:44:18 +0200
commitc3212dbda325bdf6eaff6a7652c996a28e8ba688 (patch)
treeefec5919720793ed9cbc759f7168581a31d3bd29
parentab4c1b8a8b67fd9ffc89c804efa260584530897d (diff)
Add scope::lookup_original_info() that provides additional info about lookup
-rw-r--r--libbuild2/scope.cxx44
-rw-r--r--libbuild2/scope.hxx25
-rw-r--r--libbuild2/target.cxx5
-rw-r--r--libbuild2/target.hxx10
4 files changed, 56 insertions, 28 deletions
diff --git a/libbuild2/scope.cxx b/libbuild2/scope.cxx
index 23781a8..e0bc55a 100644
--- a/libbuild2/scope.cxx
+++ b/libbuild2/scope.cxx
@@ -43,12 +43,12 @@ namespace build2
// Definition of adhoc_rule_pattern.
}
- pair<lookup, size_t> scope::
- lookup_original (const variable& var,
- const target_key* tk,
- const target_key* g1k,
- const target_key* g2k,
- size_t start_d) const
+ scope::original_info scope::
+ lookup_original_info (const variable& var,
+ const target_key* tk,
+ 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);
@@ -56,7 +56,7 @@ namespace build2
size_t d (0);
if (var.visibility == variable_visibility::prereq)
- return make_pair (lookup_type (), d);
+ return original_info {{lookup_type (), d}, false};
// Process target type/pattern-specific prepend/append values.
//
@@ -115,7 +115,7 @@ namespace build2
cv = *stem;
// Typify the cache value in case there is no stem (we still want to
- // prepend/append things in type-aware way).
+ // prepend/append things in a type-aware way).
//
if (cv.type == nullptr && var.type != nullptr)
typify (cv, *var.type, &var);
@@ -152,7 +152,7 @@ namespace build2
{
bool f (!s->target_vars.empty ());
- // Target.
+ // Target type/pattern-specific for the target.
//
if (++d >= start_d)
{
@@ -162,15 +162,16 @@ namespace build2
if (l.defined ())
{
- if (l->extra != 0) // Prepend/append?
+ bool pa (l->extra != 0); // Prepend/append?
+ if (pa)
pre_app (l, s, tk, g1k, g2k, move (*tn));
- return make_pair (move (l), d);
+ return original_info {{move (l), d}, pa};
}
}
}
- // Group.
+ // Target type/pattern-specific for the group.
//
if (++d >= start_d)
{
@@ -180,10 +181,11 @@ namespace build2
if (l.defined ())
{
- if (l->extra != 0) // Prepend/append?
+ bool pa (l->extra != 0); // Prepend/append?
+ if (pa)
pre_app (l, s, g1k, g2k, nullptr, move (*g1n));
- return make_pair (move (l), d);
+ return original_info {{move (l), d}, pa};
}
if (g2k != nullptr)
@@ -192,10 +194,11 @@ namespace build2
if (l.defined ())
{
- if (l->extra != 0) // Prepend/append?
+ bool pa (l->extra != 0); // Prepend/append?
+ if (pa)
pre_app (l, s, g2k, nullptr, nullptr, move (*g2n));
- return make_pair (move (l), d);
+ return original_info {{move (l), d}, pa};
}
}
}
@@ -209,7 +212,8 @@ namespace build2
{
auto p (s->vars.lookup (var));
if (p.first != nullptr)
- return make_pair (lookup_type (*p.first, p.second, s->vars), d);
+ return original_info {
+ {lookup_type (*p.first, p.second, s->vars), d}, false};
}
switch (var.visibility)
@@ -229,14 +233,14 @@ namespace build2
}
}
- return make_pair (lookup_type (), size_t (~0));
+ return original_info {{lookup_type (), size_t (~0)}, false};
}
- auto scope::
+ scope::override_info scope::
lookup_override_info (const variable& var,
const pair<lookup_type, size_t> original,
bool target,
- bool rule) const -> override_info
+ bool rule) const
{
assert (!rule || target); // Rule-specific is target-specific.
diff --git a/libbuild2/scope.hxx b/libbuild2/scope.hxx
index 09d61e9..f821411 100644
--- a/libbuild2/scope.hxx
+++ b/libbuild2/scope.hxx
@@ -190,12 +190,33 @@ namespace build2
// can be used to skip a number of initial lookups.
//
pair<lookup_type, size_t>
- lookup_original (const variable&,
+ lookup_original (const variable& var,
const target_key* tk = nullptr,
const target_key* g1k = nullptr,
const target_key* g2k = nullptr,
- size_t start_depth = 1) const;
+ size_t start_depth = 1) const
+ {
+ return lookup_original_info (var, tk, g1k, g2k, start_depth).lookup;
+ }
+
+ // As above but also return an indication of whether the resulting value
+ // was modified by a target type/pattern-specific append/prepend.
+ //
+ struct original_info
+ {
+ pair<lookup_type, size_t> lookup;
+ bool modified;
+ };
+ original_info
+ lookup_original_info (const variable&,
+ const target_key* tk,
+ const target_key* g1k = nullptr,
+ const target_key* g2k = nullptr,
+ size_t start_depth = 1) const;
+
+ // Implementation details (used by scope target lookup).
+ //
pair<lookup_type, size_t>
lookup_override (const variable& var,
pair<lookup_type, size_t> original,
diff --git a/libbuild2/target.cxx b/libbuild2/target.cxx
index 2a134a4..1a72788 100644
--- a/libbuild2/target.cxx
+++ b/libbuild2/target.cxx
@@ -188,9 +188,10 @@ namespace build2
// Skip looking up in the ad hoc group, which is semantically the
// first/primary member.
//
- if ((g1 = group == nullptr
+ const target* g (group); // Atomic.
+ if ((g1 = g == nullptr
? nullptr
- : group->adhoc_group () ? group->group : group))
+ : g->adhoc_group () ? static_cast<const target*> (g->group) : g))
{
auto p (g1->vars.lookup (var));
if (p.first != nullptr)
diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx
index 20cd32d..da2ab73 100644
--- a/libbuild2/target.hxx
+++ b/libbuild2/target.hxx
@@ -770,10 +770,12 @@ namespace build2
// As above but also return the depth at which the value is found. The
// depth is calculated by adding 1 for each test performed. So a value
// that is from the target will have depth 1. That from the group -- 2.
- // From the innermost scope's target type/patter-specific variables --
- // 3. From the innermost scope's variables -- 4. And so on. The idea is
- // that given two lookups from the same target, we can say which one came
- // earlier. If no value is found, then the depth is set to ~0.
+ // From the innermost scope's target type/patter-specific variables for
+ // the target -- 3. From the innermost scope's target type/patter-specific
+ // variables for the group -- 4. From the innermost scope's variables --
+ // 5. And so on. The idea is that given two lookups from the same target,
+ // we can say which one came earlier. If no value is found, then the depth
+ // is set to ~0.
//
pair<lookup_type, size_t>
lookup (const variable& var, const scope* bs = nullptr) const