blob: 7be6a6dc3abed26ad12b2c47bcdb51d371fd9ab4 [file] [log] [blame]
Shinichiro Hamaji1d545aa2015-06-23 15:29:13 +09001// Copyright 2015 Google Inc. All rights reserved
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +090015// +build ignore
16
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090017#include "dep.h"
18
Shinichiro Hamaji4a711312015-06-19 14:44:20 +090019#include <algorithm>
Shinichiro Hamaji485f9122015-06-26 07:06:14 +090020#include <iterator>
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090021#include <memory>
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +090022#include <unordered_map>
23#include <unordered_set>
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090024
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +090025#include "eval.h"
Shinichiro Hamaji0562c302015-06-19 15:30:49 +090026#include "fileutil.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090027#include "log.h"
28#include "rule.h"
Shinichiro Hamaji4a711312015-06-19 14:44:20 +090029#include "strutil.h"
Shinichiro Hamajie7992752015-06-29 18:38:35 +090030#include "symtab.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090031#include "var.h"
32
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090033namespace {
34
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090035static vector<DepNode*>* g_dep_node_pool;
36
Shinichiro Hamajie7992752015-06-29 18:38:35 +090037static Symbol ReplaceSuffix(Symbol s, Symbol newsuf) {
Shinichiro Hamaji0562c302015-06-19 15:30:49 +090038 string r;
Shinichiro Hamajie7992752015-06-29 18:38:35 +090039 AppendString(StripExt(s.str()), &r);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +090040 r += '.';
Shinichiro Hamajie7992752015-06-29 18:38:35 +090041 AppendString(newsuf.str(), &r);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +090042 return Intern(r);
43}
44
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090045class RuleTrie {
46 struct Entry {
47 Entry(shared_ptr<Rule> r, StringPiece s)
48 : rule(r), suffix(s) {
49 }
50 shared_ptr<Rule> rule;
51 StringPiece suffix;
52 };
53
54 public:
55 RuleTrie() {}
56 ~RuleTrie() {
57 for (auto& p : children_)
58 delete p.second;
59 }
60
61 void Add(StringPiece name, shared_ptr<Rule> rule) {
62 if (name.empty() || name[0] == '%') {
63 rules_.push_back(Entry(rule, name));
64 return;
65 }
66 const char c = name[0];
67 auto p = children_.emplace(c, nullptr);
68 if (p.second) {
69 p.first->second = new RuleTrie();
70 }
71 p.first->second->Add(name.substr(1), rule);
72 }
73
Shinichiro Hamajif772b172015-06-29 16:05:44 +090074 void Get(StringPiece name, vector<shared_ptr<Rule>>* rules) const {
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090075 for (const Entry& ent : rules_) {
76 if ((ent.suffix.empty() && name.empty()) ||
77 HasSuffix(name, ent.suffix.substr(1))) {
78 rules->push_back(ent.rule);
79 }
80 }
Shinichiro Hamajif772b172015-06-29 16:05:44 +090081 if (name.empty())
82 return;
83 auto found = children_.find(name[0]);
84 if (found != children_.end()) {
85 found->second->Get(name.substr(1), rules);
86 }
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090087 }
88
89 size_t size() const {
90 size_t r = rules_.size();
91 for (const auto& c : children_)
92 r += c.second->size();
93 return r;
94 }
95
96 private:
97 vector<Entry> rules_;
98 unordered_map<char, RuleTrie*> children_;
99};
100
101} // namespace
102
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900103DepNode::DepNode(Symbol o, bool p)
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900104 : output(o),
105 has_rule(false),
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900106 is_phony(p),
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900107 rule_vars(NULL),
108 output_pattern(Symbol::IsUninitialized()) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900109 g_dep_node_pool->push_back(this);
110}
111
112class DepBuilder {
113 public:
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900114 DepBuilder(Evaluator* ev,
115 const vector<shared_ptr<Rule>>& rules,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900116 const unordered_map<Symbol, Vars*>& rule_vars)
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900117 : ev_(ev),
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900118 rule_vars_(rule_vars),
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900119 implicit_rules_(new RuleTrie()),
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900120 first_rule_(NULL) {
121 PopulateRules(rules);
Shinichiro Hamajib4969af2015-06-28 02:06:54 +0900122 LOG_STAT("%zu variables", ev->mutable_vars()->size());
123 LOG_STAT("%zu explicit rules", rules_.size());
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900124 LOG_STAT("%zu implicit rules", implicit_rules_->size());
Shinichiro Hamajib4969af2015-06-28 02:06:54 +0900125 LOG_STAT("%zu suffix rules", suffix_rules_.size());
Shinichiro Hamajid40b6fe2015-06-29 17:08:42 +0900126
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900127 auto found = rules_.find(Intern(".PHONY"));
Shinichiro Hamajid40b6fe2015-06-29 17:08:42 +0900128 if (found != rules_.end()) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900129 for (Symbol input : found->second->inputs) {
Shinichiro Hamajid40b6fe2015-06-29 17:08:42 +0900130 phony_.insert(input);
131 }
132 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900133 }
134
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900135 ~DepBuilder() {
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900136 }
137
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900138 void Build(vector<Symbol> targets,
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900139 vector<DepNode*>* nodes) {
140 if (targets.empty()) {
141 if (!first_rule_) {
142 ERROR("*** No targets.");
143 }
144 CHECK(!first_rule_->outputs.empty());
Shinichiro Hamaji43defe02015-07-11 07:06:43 +0900145
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900146 targets.push_back(first_rule_->outputs[0]);
Shinichiro Hamaji319b6492015-09-24 14:23:55 +0900147 }
148 if (g_flags.gen_all_phony_targets) {
149 for (Symbol s : phony_)
150 targets.push_back(s);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900151 }
Shinichiro Hamaji7223e7b2015-09-28 15:17:27 +0900152 if (g_flags.gen_all_targets) {
153 for (const auto& p : rules_)
154 targets.push_back(p.first);
155 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900156
157 // TODO: LogStats?
158
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900159 for (Symbol target : targets) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900160 cur_rule_vars_.reset(new Vars);
161 ev_->set_current_scope(cur_rule_vars_.get());
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900162 DepNode* n = BuildPlan(target, Intern(""));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900163 nodes->push_back(n);
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900164 ev_->set_current_scope(NULL);
165 cur_rule_vars_.reset(NULL);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900166 }
167 }
168
169 private:
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900170 bool Exists(Symbol target) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900171 auto found = rules_.find(target);
172 if (found != rules_.end())
173 return true;
174 if (phony_.count(target))
175 return true;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900176 return ::Exists(target.str());
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900177 }
178
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900179 void PopulateRules(const vector<shared_ptr<Rule>>& rules) {
180 for (shared_ptr<Rule> rule : rules) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900181 if (rule->outputs.empty()) {
182 PopulateImplicitRule(rule);
183 } else {
184 PopulateExplicitRule(rule);
185 }
186 }
Shinichiro Hamaji65657d92015-06-24 17:05:50 +0900187 for (auto& p : suffix_rules_) {
188 reverse(p.second.begin(), p.second.end());
189 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900190 }
191
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900192 bool PopulateSuffixRule(shared_ptr<Rule> rule, Symbol output) {
193 if (output.empty() || output.str()[0] != '.')
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900194 return false;
195
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900196 const StringPiece rest = StringPiece(output.str()).substr(1);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900197 size_t dot_index = rest.find('.');
198 // If there is only a single dot or the third dot, this is not a
199 // suffix rule.
200 if (dot_index == string::npos ||
201 rest.substr(dot_index+1).find('.') != string::npos) {
202 return false;
203 }
204
205 StringPiece input_suffix = rest.substr(0, dot_index);
206 StringPiece output_suffix = rest.substr(dot_index+1);
207 shared_ptr<Rule> r = make_shared<Rule>(*rule);
208 r->inputs.clear();
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900209 r->inputs.push_back(Intern(input_suffix));
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900210 r->is_suffix_rule = true;
211 suffix_rules_[output_suffix].push_back(r);
212 return true;
213 }
214
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900215 void ApplyOutputPattern(const Rule& r,
216 Symbol output,
217 const vector<Symbol>& inputs,
218 vector<Symbol>* out_inputs) {
219 if (inputs.empty())
220 return;
221 if (r.is_suffix_rule) {
222 for (Symbol input : inputs) {
223 out_inputs->push_back(ReplaceSuffix(output, input));
224 }
225 return;
226 }
227 if (r.output_patterns.empty()) {
228 copy(inputs.begin(), inputs.end(), back_inserter(*out_inputs));
229 return;
230 }
231 CHECK(r.output_patterns.size() == 1);
232 Pattern pat(r.output_patterns[0].str());
233 for (Symbol input : inputs) {
234 string buf;
235 pat.AppendSubst(output.str(), input.str(), &buf);
236 out_inputs->push_back(Intern(buf));
237 }
238 }
239
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900240 shared_ptr<Rule> MergeRules(const Rule& old_rule,
241 const Rule& rule,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900242 Symbol output,
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900243 bool is_suffix_rule) {
244 if (old_rule.is_double_colon != rule.is_double_colon) {
245 ERROR("%s:%d: *** target file `%s' has both : and :: entries.",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900246 LOCF(rule.loc), output.str().c_str());
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900247 }
248 if (!old_rule.cmds.empty() && !rule.cmds.empty() &&
249 !is_suffix_rule && !rule.is_double_colon) {
Shinichiro Hamajiff4584d2015-06-24 17:45:14 +0900250 WARN("%s:%d: warning: overriding commands for target `%s'",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900251 LOCF(rule.cmd_loc()), output.str().c_str());
Shinichiro Hamajiff4584d2015-06-24 17:45:14 +0900252 WARN("%s:%d: warning: ignoring old commands for target `%s'",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900253 LOCF(old_rule.cmd_loc()), output.str().c_str());
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900254 }
255
256 shared_ptr<Rule> r = make_shared<Rule>(rule);
257 if (rule.is_double_colon) {
258 r->cmds.clear();
259 for (Value* c : old_rule.cmds)
260 r->cmds.push_back(c);
261 for (Value* c : rule.cmds)
262 r->cmds.push_back(c);
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900263 if (!rule.output_patterns.empty() && !old_rule.output_patterns.empty() &&
264 rule.output_patterns != old_rule.output_patterns) {
265 ERROR("%s:%d: TODO: merging two double rules with output patterns "
266 "is not supported", LOCF(rule.loc));
267 }
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900268 } else if (!old_rule.cmds.empty() && rule.cmds.empty()) {
269 r->cmds = old_rule.cmds;
270 }
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900271
Shinichiro Hamaji2e23e4a2015-06-26 07:33:16 +0900272 // If the latter rule has a command (regardless of the commands in
273 // |old_rule|), inputs in the latter rule has a priority.
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900274 if (rule.cmds.empty()) {
275 r->inputs = old_rule.inputs;
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900276 ApplyOutputPattern(rule, output, rule.inputs, &r->inputs);
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900277 r->order_only_inputs = old_rule.order_only_inputs;
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900278 ApplyOutputPattern(rule, output, rule.order_only_inputs,
279 &r->order_only_inputs);
280 r->output_patterns = old_rule.output_patterns;
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900281 } else {
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900282 ApplyOutputPattern(old_rule, output, old_rule.inputs, &r->inputs);
283 ApplyOutputPattern(old_rule, output, old_rule.order_only_inputs,
284 &r->order_only_inputs);
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900285 }
286 return r;
287 }
288
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900289 void PopulateExplicitRule(shared_ptr<Rule> orig_rule) {
290 for (Symbol output : orig_rule->outputs) {
291 const bool is_suffix_rule = PopulateSuffixRule(orig_rule, output);
Shinichiro Hamajie36dd562015-06-27 16:34:48 +0900292
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900293 shared_ptr<Rule> rule = make_shared<Rule>(*orig_rule);
Shinichiro Hamajie36dd562015-06-27 16:34:48 +0900294 rule->outputs.clear();
295 rule->outputs.push_back(output);
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900296
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900297 auto p = rules_.insert(make_pair(output, rule));
298 if (p.second) {
299 if (!first_rule_ && output.get(0) != '.') {
300 first_rule_ = rule;
301 }
302 } else {
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900303 p.first->second =
304 MergeRules(*p.first->second, *rule, output, is_suffix_rule);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900305 }
306 }
307 }
308
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900309 void PopulateImplicitRule(shared_ptr<Rule> rule) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900310 for (Symbol output_pattern : rule->output_patterns) {
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900311 shared_ptr<Rule> r = make_shared<Rule>(*rule);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900312 r->output_patterns.clear();
313 r->output_patterns.push_back(output_pattern);
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900314 implicit_rules_->Add(output_pattern.str(), r);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900315 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900316 }
317
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900318 shared_ptr<Rule> LookupRule(Symbol o) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900319 auto found = rules_.find(o);
320 if (found != rules_.end())
321 return found->second;
322 return NULL;
323 }
324
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900325 Vars* LookupRuleVars(Symbol o) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900326 auto found = rule_vars_.find(o);
327 if (found != rule_vars_.end())
328 return found->second;
329 return NULL;
330 }
331
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900332 bool CanPickImplicitRule(shared_ptr<Rule> rule, Symbol output) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900333 CHECK(rule->output_patterns.size() == 1);
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900334 Pattern pat(rule->output_patterns[0].str());
335 if (!pat.Match(output.str())) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900336 return false;
337 }
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900338 for (Symbol input : rule->inputs) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900339 string buf;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900340 pat.AppendSubst(output.str(), input.str(), &buf);
341 if (!Exists(Intern(buf)))
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900342 return false;
343 }
344 return true;
345 }
346
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900347 Vars* MergeImplicitRuleVars(Symbol output, Vars* vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900348 auto found = rule_vars_.find(output);
349 if (found == rule_vars_.end())
350 return vars;
351 if (vars == NULL)
352 return found->second;
353 // TODO: leak.
354 Vars* r = new Vars(*found->second);
355 for (auto p : *vars) {
356 (*r)[p.first] = p.second;
357 }
358 return r;
359 }
360
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900361 bool PickRule(Symbol output,
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900362 shared_ptr<Rule>* out_rule, Vars** out_var) {
363 shared_ptr<Rule> rule = LookupRule(output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900364 Vars* vars = LookupRuleVars(output);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900365 *out_rule = rule;
366 *out_var = vars;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900367 if (rule) {
368 if (!rule->cmds.empty()) {
369 return true;
370 }
371 }
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900372
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900373 vector<shared_ptr<Rule>> irules;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900374 implicit_rules_->Get(output.str(), &irules);
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900375 for (auto iter = irules.rbegin(); iter != irules.rend(); ++iter) {
376 shared_ptr<Rule> irule = *iter;
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900377 if (!CanPickImplicitRule(irule, output))
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900378 continue;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900379 if (rule) {
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900380 shared_ptr<Rule> r = make_shared<Rule>(*rule);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900381 r->output_patterns = irule->output_patterns;
Shinichiro Hamajid2c0fe12015-06-26 07:42:53 +0900382 r->inputs.clear();
383 r->inputs = irule->inputs;
384 copy(rule->inputs.begin(), rule->inputs.end(),
385 back_inserter(r->inputs));
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900386 r->cmds = irule->cmds;
387 r->loc = irule->loc;
388 r->cmd_lineno = irule->cmd_lineno;
389 *out_rule = r;
390 return true;
391 }
392 if (vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900393 CHECK(irule->output_patterns.size() == 1);
394 vars = MergeImplicitRuleVars(irule->output_patterns[0], vars);
395 *out_var = vars;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900396 }
397 *out_rule = irule;
398 return true;
399 }
400
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900401 StringPiece output_suffix = GetExt(output.str());
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900402 if (output_suffix.get(0) != '.')
403 return rule.get();
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900404 output_suffix = output_suffix.substr(1);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900405
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900406 SuffixRuleMap::const_iterator found = suffix_rules_.find(output_suffix);
407 if (found == suffix_rules_.end())
408 return rule.get();
409
410 for (shared_ptr<Rule> irule : found->second) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900411 CHECK(irule->inputs.size() == 1);
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900412 Symbol input = ReplaceSuffix(output, irule->inputs[0]);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900413 if (!Exists(input))
414 continue;
415
416 if (rule) {
417 shared_ptr<Rule> r = make_shared<Rule>(*rule);
418 r->inputs.insert(r->inputs.begin(), input);
419 r->cmds = irule->cmds;
420 r->loc = irule->loc;
421 r->cmd_lineno = irule->cmd_lineno;
422 *out_rule = r;
423 return true;
424 }
425 if (vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900426 CHECK(irule->outputs.size() == 1);
427 vars = MergeImplicitRuleVars(irule->outputs[0], vars);
428 *out_var = vars;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900429 }
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900430 *out_rule = irule;
431 return true;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900432 }
433
434 return rule.get();
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900435 }
436
Shinichiro Hamaji8d503012015-07-03 16:26:15 +0900437 DepNode* BuildPlan(Symbol output, Symbol needed_by UNUSED) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900438 LOG("BuildPlan: %s for %s",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900439 output.c_str(),
440 needed_by.c_str());
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900441
442 auto found = done_.find(output);
443 if (found != done_.end()) {
444 return found->second;
445 }
446
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900447 DepNode* n = new DepNode(output, phony_.count(output));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900448 done_[output] = n;
449
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900450 shared_ptr<Rule> rule;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900451 Vars* vars;
452 if (!PickRule(output, &rule, &vars)) {
453 return n;
454 }
455
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900456 if (rule->output_patterns.size() >= 1) {
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900457 if (rule->output_patterns.size() != 1) {
458 fprintf(stderr, "hmm %s\n", rule->DebugString().c_str());
459 }
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900460 CHECK(rule->output_patterns.size() == 1);
461 n->output_pattern = rule->output_patterns[0];
462 }
463
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900464 vector<unique_ptr<ScopedVar>> sv;
465 if (vars) {
466 for (const auto& p : *vars) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900467 Symbol name = p.first;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900468 RuleVar* var = reinterpret_cast<RuleVar*>(p.second);
469 CHECK(var);
470 Var* new_var = var->v();
471 if (var->op() == AssignOp::PLUS_EQ) {
472 Var* old_var = ev_->LookupVar(name);
473 if (old_var->IsDefined()) {
474 // TODO: This would be incorrect and has a leak.
475 shared_ptr<string> s = make_shared<string>();
476 old_var->Eval(ev_, s.get());
Shinichiro Hamaji3c785c72015-06-23 19:22:34 +0900477 if (!s->empty())
478 *s += ' ';
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900479 new_var->Eval(ev_, s.get());
Shinichiro Hamaji5081c712015-08-14 16:49:20 +0900480 new_var = new SimpleVar(*s, old_var->Origin());
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900481 }
482 } else if (var->op() == AssignOp::QUESTION_EQ) {
483 Var* old_var = ev_->LookupVar(name);
484 if (old_var->IsDefined()) {
485 continue;
486 }
487 }
Shinichiro Hamajie978a892015-08-17 16:53:40 +0900488 sv.emplace_back(new ScopedVar(cur_rule_vars_.get(), name, new_var));
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900489 }
490 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900491
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900492 ApplyOutputPattern(*rule, output, rule->inputs, &n->actual_inputs);
493 for (Symbol input : n->actual_inputs) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900494 DepNode* c = BuildPlan(input, output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900495 n->deps.push_back(c);
496 }
497
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900498 vector<Symbol> order_only_inputs;
499 ApplyOutputPattern(*rule, output, rule->order_only_inputs,
500 &order_only_inputs);
501 for (Symbol input : order_only_inputs) {
Shinichiro Hamaji704e4fe2015-06-24 17:37:47 +0900502 DepNode* c = BuildPlan(input, output);
Shinichiro Hamaji183dbb92015-07-06 17:21:39 +0900503 n->order_onlys.push_back(c);
Shinichiro Hamaji704e4fe2015-06-24 17:37:47 +0900504 }
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900505
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900506 n->has_rule = true;
507 n->cmds = rule->cmds;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900508 if (cur_rule_vars_->empty()) {
509 n->rule_vars = NULL;
510 } else {
511 n->rule_vars = new Vars;
512 for (auto p : *cur_rule_vars_) {
513 n->rule_vars->insert(p);
514 }
515 }
516 n->loc = rule->loc;
517 if (!rule->cmds.empty() && rule->cmd_lineno)
518 n->loc.lineno = rule->cmd_lineno;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900519
520 return n;
521 }
522
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900523 Evaluator* ev_;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900524 unordered_map<Symbol, shared_ptr<Rule>> rules_;
525 const unordered_map<Symbol, Vars*>& rule_vars_;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900526 unique_ptr<Vars> cur_rule_vars_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900527
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900528 unique_ptr<RuleTrie> implicit_rules_;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900529 typedef unordered_map<StringPiece, vector<shared_ptr<Rule>>> SuffixRuleMap;
530 SuffixRuleMap suffix_rules_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900531
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900532 shared_ptr<Rule> first_rule_;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900533 unordered_map<Symbol, DepNode*> done_;
534 unordered_set<Symbol> phony_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900535};
536
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900537void MakeDep(Evaluator* ev,
538 const vector<shared_ptr<Rule>>& rules,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900539 const unordered_map<Symbol, Vars*>& rule_vars,
540 const vector<Symbol>& targets,
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900541 vector<DepNode*>* nodes) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900542 DepBuilder db(ev, rules, rule_vars);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900543 db.Build(targets, nodes);
544}
545
546void InitDepNodePool() {
547 g_dep_node_pool = new vector<DepNode*>;
548}
549
550void QuitDepNodePool() {
551 for (DepNode* n : *g_dep_node_pool)
552 delete n;
553 delete g_dep_node_pool;
554}