aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-12-03 13:58:28 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-12-03 13:58:28 +0200
commit721835d4dd0fe306e4b55d425f9360fac592eace (patch)
treec6358c198a444d2ce387942e17e22c8bac7f55b7
parentc49b0e8ca53928cc20e9d4832536baaeee6d7a9d (diff)
Allow typification of variables and values across load generations
The original semantics turned out to be too restrictive. For example, the user may have specified the config.c variable on the command line that is only used by an imported project that is loaded in a subsequent generation. We are also relaxing it for values since conceptually the two feel the same. For a value the (hypothetical) example is a "common" variable set in a project root that is only queried in a subdirectory in a subsequent generation.
-rw-r--r--build2/context.cxx2
-rw-r--r--build2/context.hxx15
-rw-r--r--build2/scope.hxx2
-rw-r--r--build2/test/script/script.cxx1
-rw-r--r--build2/variable.cxx26
-rw-r--r--build2/variable.hxx2
6 files changed, 14 insertions, 34 deletions
diff --git a/build2/context.cxx b/build2/context.cxx
index 1b5bb0b..b359d8f 100644
--- a/build2/context.cxx
+++ b/build2/context.cxx
@@ -602,7 +602,7 @@ namespace build2
//
if (o->override == nullptr)
const_cast<variable*> (o)->override.reset (
- new variable {n + k, nullptr, nullptr, v, 0});
+ new variable {n + k, nullptr, nullptr, v});
o = o->override.get ();
diff --git a/build2/context.hxx b/build2/context.hxx
index 5815f51..434b41f 100644
--- a/build2/context.hxx
+++ b/build2/context.hxx
@@ -41,13 +41,14 @@ namespace build2
//
// Serial load can perform arbitrary changes to the model. Exclusive load,
// however, can only perform "island appends". That is, it can create new
- // "nodes" (variables, scopes, etc) but not change already existing nodes or
- // invalidate any references to such (the idea here is that one should be
- // able to load additional buildfiles as long as they don't interfere with
- // the existing build state). The "islands" are identified by the
- // load_generation number (0 for initial/serial load). It is incremented in
- // case of a phase switch and is stored in various "nodes" (variables, etc)
- // to allow modifications "within the islands".
+ // "nodes" (variables, scopes, etc) but not (semantically) change already
+ // existing nodes or invalidate any references to such (the idea here is
+ // that one should be able to load additional buildfiles as long as they
+ // don't interfere with the existing build state). The "islands" are
+ // identified by the load_generation number (0 for the initial/serial
+ // load). It is incremented in case of a phase switch and can be stored in
+ // various "nodes" to verify modifications are only done "within the
+ // islands".
//
extern run_phase phase;
extern size_t load_generation;
diff --git a/build2/scope.hxx b/build2/scope.hxx
index 00aba52..5d0fcd8 100644
--- a/build2/scope.hxx
+++ b/build2/scope.hxx
@@ -316,7 +316,7 @@ namespace build2
// Temporary scope. The idea is to be able to create a temporary scope in
// order not to change the variables in the current scope. Such a scope is
// not entered in to the scope map. As a result it can only be used as a
- // temporary set of variables. In particular, defining targetsdirectly in
+ // temporary set of variables. In particular, defining targets directly in
// such a scope will surely end up badly. Defining any nested scopes will be
// as if defining such a scope in the parent (since path() returns parent's
// path).
diff --git a/build2/test/script/script.cxx b/build2/test/script/script.cxx
index eb366c1..5a9ad3c 100644
--- a/build2/test/script/script.cxx
+++ b/build2/test/script/script.cxx
@@ -438,6 +438,7 @@ namespace build2
scope (const string& id, scope* p)
: parent (p),
root (p != nullptr ? p->root : static_cast<script*> (this)),
+ vars (false /* global */),
id_path (cast<path> (assign (root->id_var) = path ())),
wd_path (cast<dir_path> (assign (root->wd_var) = dir_path ()))
diff --git a/build2/variable.cxx b/build2/variable.cxx
index 1afa872..8d9aa14 100644
--- a/build2/variable.cxx
+++ b/build2/variable.cxx
@@ -1016,16 +1016,6 @@ namespace build2
bool ut (t != nullptr && var.type != t);
bool uv (v != nullptr && var.visibility != *v);
- // In the global pool existing variables can only be updated during the
- // same load generation or during serial execution.
- //
- if (global_ &&
- load_generation != 0 &&
- load_generation != var.generation &&
- (ut || uv))
- fail << "variable " << var.name << " already defined with different "
- << (ut ? (uv ? "type and visibility" : "type") : "visibility");
-
// Update type?
//
if (ut)
@@ -1141,8 +1131,7 @@ namespace build2
move (n),
t,
nullptr,
- v != nullptr ? *v : variable_visibility::normal,
- global_ ? load_generation : 0}));
+ v != nullptr ? *v : variable_visibility::normal}));
variable& r (p.first->second);
@@ -1233,16 +1222,9 @@ namespace build2
// variable_map
//
- void variable_map::
+ inline void variable_map::
typify (value_data& v, const variable& var) const
{
- // In the global state existing value can only be typified during
- // the same load generation or during serial execution.
- //
- assert (!global_ ||
- load_generation == 0 ||
- v.generation == load_generation);
-
// We assume typification is not modification.
//
build2::typify (v, *var.type, &var);
@@ -1286,9 +1268,7 @@ namespace build2
auto p (m_.emplace (var, value_data (typed ? var.type : nullptr)));
value_data& r (p.first->second);
- if (p.second)
- r.generation = global_ ? load_generation : 0;
- else
+ if (!p.second)
{
// First access after being assigned a type?
//
diff --git a/build2/variable.hxx b/build2/variable.hxx
index f3eea63..60a1699 100644
--- a/build2/variable.hxx
+++ b/build2/variable.hxx
@@ -123,7 +123,6 @@ namespace build2
const value_type* type; // If NULL, then not (yet) typed.
unique_ptr<variable> override;
variable_visibility visibility;
- size_t generation; // load_generation of this variable.
};
inline bool
@@ -1070,7 +1069,6 @@ namespace build2
using value::operator=;
size_t version = 0; // Incremented on each modification (variable_cache).
- size_t generation; // load_generation of this value (global state only).
};
using map_type = butl::prefix_map<reference_wrapper<const variable>,