Move a common loop into the new function RecomputeOutputsDirty().
Simplifies things a bit, and makes it harder for the restat path to have
different behavior from the regular path.
No dramatic behavior change (the restat path now also calls
RestatIfNecessary()).
begin = (*ei)->inputs_.begin(),
end = (*ei)->inputs_.end() - (*ei)->order_only_deps_;
if (find_if(begin, end, mem_fun(&Node::dirty)) == end) {
- // Recompute most_recent_input and command.
+ // Recompute most_recent_input.
Node* most_recent_input = NULL;
for (vector<Node*>::iterator ni = begin; ni != end; ++ni) {
if (!most_recent_input || (*ni)->mtime() > most_recent_input->mtime())
most_recent_input = *ni;
}
- string command = (*ei)->EvaluateCommand(true);
// Now, this edge is dirty if any of the outputs are dirty.
- bool dirty = false;
- for (vector<Node*>::iterator ni = (*ei)->outputs_.begin();
- !dirty && ni != (*ei)->outputs_.end(); ++ni) {
- dirty = scan->RecomputeOutputDirty(*ei, most_recent_input,
- command, *ni);
- }
-
// If the edge isn't dirty, clean the outputs and mark the edge as not
// wanted.
- if (!dirty) {
+ if (!scan->RecomputeOutputsDirty(*ei, most_recent_input)) {
for (vector<Node*>::iterator ni = (*ei)->outputs_.begin();
ni != (*ei)->outputs_.end(); ++ni) {
CleanNode(scan, *ni);
// We may also be dirty due to output state: missing outputs, out of
// date outputs, etc. Visit all outputs and determine whether they're dirty.
- if (!dirty) {
- string command = edge->EvaluateCommand(true);
-
- for (vector<Node*>::iterator i = edge->outputs_.begin();
- i != edge->outputs_.end(); ++i) {
- (*i)->StatIfNecessary(disk_interface_);
- if (RecomputeOutputDirty(edge, most_recent_input, command, *i)) {
- dirty = true;
- break;
- }
- }
- }
+ if (!dirty)
+ dirty = RecomputeOutputsDirty(edge, most_recent_input);
// Finally, visit each output to mark off that we've visited it, and update
// their dirty state if necessary.
return true;
}
+bool DependencyScan::RecomputeOutputsDirty(Edge* edge,
+ Node* most_recent_input) {
+ string command = edge->EvaluateCommand(true);
+ for (vector<Node*>::iterator i = edge->outputs_.begin();
+ i != edge->outputs_.end(); ++i) {
+ (*i)->StatIfNecessary(disk_interface_);
+ if (RecomputeOutputDirty(edge, most_recent_input, command, *i))
+ return true;
+ }
+ return false;
+}
+
bool DependencyScan::RecomputeOutputDirty(Edge* edge,
Node* most_recent_input,
const string& command,
/// Returns false on failure.
bool RecomputeDirty(Edge* edge, string* err);
- /// Recompute whether a given single output should be marked dirty.
+ /// Recompute whether any output of the edge is dirty.
/// Returns true if so.
- bool RecomputeOutputDirty(Edge* edge, Node* most_recent_input,
- const string& command, Node* output);
+ bool RecomputeOutputsDirty(Edge* edge, Node* most_recent_input);
BuildLog* build_log() const {
return build_log_;
}
private:
+ /// Recompute whether a given single output should be marked dirty.
+ /// Returns true if so.
+ bool RecomputeOutputDirty(Edge* edge, Node* most_recent_input,
+ const string& command, Node* output);
+
BuildLog* build_log_;
DiskInterface* disk_interface_;
ImplicitDepLoader dep_loader_;