From 9ca783f9fab41eac40b96313749533ea5c965426 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 28 Jun 2018 11:04:24 +0200 Subject: Add prerequisite variable visibility specification/enforcement --- build2/parser.cxx | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) (limited to 'build2/parser.cxx') diff --git a/build2/parser.cxx b/build2/parser.cxx index dfa9916..4fe30e9 100644 --- a/build2/parser.cxx +++ b/build2/parser.cxx @@ -544,6 +544,12 @@ namespace build2 const variable& var (parse_variable_name (move (pns), ploc)); apply_variable_attributes (var); + if (var.visibility >= variable_visibility::prereq) + { + fail (nloc) << "variable " << var << " has " << var.visibility + << " visibility but is assigned in a target"; + } + // If we have multiple targets, then we save the value tokens when // parsing the first one and then replay them for the subsequent. // We have to do it this way because the value may contain @@ -898,10 +904,16 @@ namespace build2 const variable& var (parse_variable_name (move (ns), nloc)); apply_variable_attributes (var); - if (var.visibility == variable_visibility::target) - fail (nloc) << "variable " << var << " has target visibility but " - << "assigned in a scope" << - info << "consider changing to '*: " << var << "'"; + if (var.visibility >= variable_visibility::target) + { + diag_record dr (fail (nloc)); + + dr << "variable " << var << " has " << var.visibility + << " visibility but is assigned in a scope"; + + if (var.visibility == variable_visibility::target) + dr << info << "consider changing it to '*: " << var << "'"; + } { enter_scope sg (d.empty () @@ -1325,6 +1337,8 @@ namespace build2 // auto at (attributes_push (t, tt)); + const location vloc (get_location (t)); + if (tt == type::word) { // Split the token into the variable name and value at position (p) of @@ -1395,6 +1409,12 @@ namespace build2 { apply_variable_attributes (*var); + if (var->visibility >= variable_visibility::target) + { + fail (vloc) << "variable " << *var << " has " << var->visibility + << " visibility but is assigned in import"; + } + val = atype == type::assign ? &scope_->assign (*var) : &scope_->append (*var); @@ -1770,9 +1790,11 @@ namespace build2 const variable& var (parse_variable_name (move (vns), vloc)); apply_variable_attributes (var); - if (var.visibility == variable_visibility::target) - fail (vloc) << "variable " << var << " has target visibility but " - << "assigned in for-loop"; + if (var.visibility >= variable_visibility::target) + { + fail (vloc) << "variable " << var << " has " << var.visibility + << " visibility but is assigned in for-loop"; + } // Now the value (list of names) to iterate over. Parse it as a variable // value to get expansion, attributes, etc. @@ -4701,9 +4723,13 @@ namespace build2 // const auto& var (var_pool.rw (*scope_).insert (move (name), true)); - if (target_ == nullptr && var.visibility == variable_visibility::target) - fail (loc) << "variable " << var << " has target visibility but " - << "expanded in a scope"; + if ((var.visibility == variable_visibility::prereq) || + (var.visibility == variable_visibility::target && target_ == nullptr)) + { + fail (loc) << "variable " << var << " has " << var.visibility + << " visibility but is expanded in a " + << (target_ != nullptr ? "target" : "scope"); + } return target_ != nullptr ? (*target_)[var] : (*scope_)[var]; -- cgit v1.1