blob: b2480f72413329309cc0ed13fd2945cb4a6a1b56 [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 }
152
153 // TODO: LogStats?
154
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900155 for (Symbol target : targets) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900156 cur_rule_vars_.reset(new Vars);
157 ev_->set_current_scope(cur_rule_vars_.get());
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900158 DepNode* n = BuildPlan(target, Intern(""));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900159 nodes->push_back(n);
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900160 ev_->set_current_scope(NULL);
161 cur_rule_vars_.reset(NULL);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900162 }
163 }
164
165 private:
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900166 bool Exists(Symbol target) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900167 auto found = rules_.find(target);
168 if (found != rules_.end())
169 return true;
170 if (phony_.count(target))
171 return true;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900172 return ::Exists(target.str());
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900173 }
174
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900175 void PopulateRules(const vector<shared_ptr<Rule>>& rules) {
176 for (shared_ptr<Rule> rule : rules) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900177 if (rule->outputs.empty()) {
178 PopulateImplicitRule(rule);
179 } else {
180 PopulateExplicitRule(rule);
181 }
182 }
Shinichiro Hamaji65657d92015-06-24 17:05:50 +0900183 for (auto& p : suffix_rules_) {
184 reverse(p.second.begin(), p.second.end());
185 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900186 }
187
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900188 bool PopulateSuffixRule(shared_ptr<Rule> rule, Symbol output) {
189 if (output.empty() || output.str()[0] != '.')
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900190 return false;
191
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900192 const StringPiece rest = StringPiece(output.str()).substr(1);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900193 size_t dot_index = rest.find('.');
194 // If there is only a single dot or the third dot, this is not a
195 // suffix rule.
196 if (dot_index == string::npos ||
197 rest.substr(dot_index+1).find('.') != string::npos) {
198 return false;
199 }
200
201 StringPiece input_suffix = rest.substr(0, dot_index);
202 StringPiece output_suffix = rest.substr(dot_index+1);
203 shared_ptr<Rule> r = make_shared<Rule>(*rule);
204 r->inputs.clear();
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900205 r->inputs.push_back(Intern(input_suffix));
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900206 r->is_suffix_rule = true;
207 suffix_rules_[output_suffix].push_back(r);
208 return true;
209 }
210
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900211 void ApplyOutputPattern(const Rule& r,
212 Symbol output,
213 const vector<Symbol>& inputs,
214 vector<Symbol>* out_inputs) {
215 if (inputs.empty())
216 return;
217 if (r.is_suffix_rule) {
218 for (Symbol input : inputs) {
219 out_inputs->push_back(ReplaceSuffix(output, input));
220 }
221 return;
222 }
223 if (r.output_patterns.empty()) {
224 copy(inputs.begin(), inputs.end(), back_inserter(*out_inputs));
225 return;
226 }
227 CHECK(r.output_patterns.size() == 1);
228 Pattern pat(r.output_patterns[0].str());
229 for (Symbol input : inputs) {
230 string buf;
231 pat.AppendSubst(output.str(), input.str(), &buf);
232 out_inputs->push_back(Intern(buf));
233 }
234 }
235
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900236 shared_ptr<Rule> MergeRules(const Rule& old_rule,
237 const Rule& rule,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900238 Symbol output,
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900239 bool is_suffix_rule) {
240 if (old_rule.is_double_colon != rule.is_double_colon) {
241 ERROR("%s:%d: *** target file `%s' has both : and :: entries.",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900242 LOCF(rule.loc), output.str().c_str());
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900243 }
244 if (!old_rule.cmds.empty() && !rule.cmds.empty() &&
245 !is_suffix_rule && !rule.is_double_colon) {
Shinichiro Hamajiff4584d2015-06-24 17:45:14 +0900246 WARN("%s:%d: warning: overriding commands for target `%s'",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900247 LOCF(rule.cmd_loc()), output.str().c_str());
Shinichiro Hamajiff4584d2015-06-24 17:45:14 +0900248 WARN("%s:%d: warning: ignoring old commands for target `%s'",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900249 LOCF(old_rule.cmd_loc()), output.str().c_str());
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900250 }
251
252 shared_ptr<Rule> r = make_shared<Rule>(rule);
253 if (rule.is_double_colon) {
254 r->cmds.clear();
255 for (Value* c : old_rule.cmds)
256 r->cmds.push_back(c);
257 for (Value* c : rule.cmds)
258 r->cmds.push_back(c);
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900259 if (!rule.output_patterns.empty() && !old_rule.output_patterns.empty() &&
260 rule.output_patterns != old_rule.output_patterns) {
261 ERROR("%s:%d: TODO: merging two double rules with output patterns "
262 "is not supported", LOCF(rule.loc));
263 }
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900264 } else if (!old_rule.cmds.empty() && rule.cmds.empty()) {
265 r->cmds = old_rule.cmds;
266 }
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900267
Shinichiro Hamaji2e23e4a2015-06-26 07:33:16 +0900268 // If the latter rule has a command (regardless of the commands in
269 // |old_rule|), inputs in the latter rule has a priority.
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900270 if (rule.cmds.empty()) {
271 r->inputs = old_rule.inputs;
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900272 ApplyOutputPattern(rule, output, rule.inputs, &r->inputs);
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900273 r->order_only_inputs = old_rule.order_only_inputs;
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900274 ApplyOutputPattern(rule, output, rule.order_only_inputs,
275 &r->order_only_inputs);
276 r->output_patterns = old_rule.output_patterns;
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900277 } else {
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900278 ApplyOutputPattern(old_rule, output, old_rule.inputs, &r->inputs);
279 ApplyOutputPattern(old_rule, output, old_rule.order_only_inputs,
280 &r->order_only_inputs);
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900281 }
282 return r;
283 }
284
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900285 void PopulateExplicitRule(shared_ptr<Rule> orig_rule) {
286 for (Symbol output : orig_rule->outputs) {
287 const bool is_suffix_rule = PopulateSuffixRule(orig_rule, output);
Shinichiro Hamajie36dd562015-06-27 16:34:48 +0900288
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900289 shared_ptr<Rule> rule = make_shared<Rule>(*orig_rule);
Shinichiro Hamajie36dd562015-06-27 16:34:48 +0900290 rule->outputs.clear();
291 rule->outputs.push_back(output);
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900292
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900293 auto p = rules_.insert(make_pair(output, rule));
294 if (p.second) {
295 if (!first_rule_ && output.get(0) != '.') {
296 first_rule_ = rule;
297 }
298 } else {
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900299 p.first->second =
300 MergeRules(*p.first->second, *rule, output, is_suffix_rule);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900301 }
302 }
303 }
304
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900305 void PopulateImplicitRule(shared_ptr<Rule> rule) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900306 for (Symbol output_pattern : rule->output_patterns) {
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900307 shared_ptr<Rule> r = make_shared<Rule>(*rule);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900308 r->output_patterns.clear();
309 r->output_patterns.push_back(output_pattern);
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900310 implicit_rules_->Add(output_pattern.str(), r);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900311 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900312 }
313
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900314 shared_ptr<Rule> LookupRule(Symbol o) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900315 auto found = rules_.find(o);
316 if (found != rules_.end())
317 return found->second;
318 return NULL;
319 }
320
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900321 Vars* LookupRuleVars(Symbol o) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900322 auto found = rule_vars_.find(o);
323 if (found != rule_vars_.end())
324 return found->second;
325 return NULL;
326 }
327
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900328 bool CanPickImplicitRule(shared_ptr<Rule> rule, Symbol output) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900329 CHECK(rule->output_patterns.size() == 1);
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900330 Pattern pat(rule->output_patterns[0].str());
331 if (!pat.Match(output.str())) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900332 return false;
333 }
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900334 for (Symbol input : rule->inputs) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900335 string buf;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900336 pat.AppendSubst(output.str(), input.str(), &buf);
337 if (!Exists(Intern(buf)))
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900338 return false;
339 }
340 return true;
341 }
342
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900343 Vars* MergeImplicitRuleVars(Symbol output, Vars* vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900344 auto found = rule_vars_.find(output);
345 if (found == rule_vars_.end())
346 return vars;
347 if (vars == NULL)
348 return found->second;
349 // TODO: leak.
350 Vars* r = new Vars(*found->second);
351 for (auto p : *vars) {
352 (*r)[p.first] = p.second;
353 }
354 return r;
355 }
356
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900357 bool PickRule(Symbol output,
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900358 shared_ptr<Rule>* out_rule, Vars** out_var) {
359 shared_ptr<Rule> rule = LookupRule(output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900360 Vars* vars = LookupRuleVars(output);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900361 *out_rule = rule;
362 *out_var = vars;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900363 if (rule) {
364 if (!rule->cmds.empty()) {
365 return true;
366 }
367 }
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900368
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900369 vector<shared_ptr<Rule>> irules;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900370 implicit_rules_->Get(output.str(), &irules);
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900371 for (auto iter = irules.rbegin(); iter != irules.rend(); ++iter) {
372 shared_ptr<Rule> irule = *iter;
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900373 if (!CanPickImplicitRule(irule, output))
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900374 continue;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900375 if (rule) {
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900376 shared_ptr<Rule> r = make_shared<Rule>(*rule);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900377 r->output_patterns = irule->output_patterns;
Shinichiro Hamajid2c0fe12015-06-26 07:42:53 +0900378 r->inputs.clear();
379 r->inputs = irule->inputs;
380 copy(rule->inputs.begin(), rule->inputs.end(),
381 back_inserter(r->inputs));
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900382 r->cmds = irule->cmds;
383 r->loc = irule->loc;
384 r->cmd_lineno = irule->cmd_lineno;
385 *out_rule = r;
386 return true;
387 }
388 if (vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900389 CHECK(irule->output_patterns.size() == 1);
390 vars = MergeImplicitRuleVars(irule->output_patterns[0], vars);
391 *out_var = vars;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900392 }
393 *out_rule = irule;
394 return true;
395 }
396
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900397 StringPiece output_suffix = GetExt(output.str());
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900398 if (output_suffix.get(0) != '.')
399 return rule.get();
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900400 output_suffix = output_suffix.substr(1);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900401
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900402 SuffixRuleMap::const_iterator found = suffix_rules_.find(output_suffix);
403 if (found == suffix_rules_.end())
404 return rule.get();
405
406 for (shared_ptr<Rule> irule : found->second) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900407 CHECK(irule->inputs.size() == 1);
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900408 Symbol input = ReplaceSuffix(output, irule->inputs[0]);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900409 if (!Exists(input))
410 continue;
411
412 if (rule) {
413 shared_ptr<Rule> r = make_shared<Rule>(*rule);
414 r->inputs.insert(r->inputs.begin(), input);
415 r->cmds = irule->cmds;
416 r->loc = irule->loc;
417 r->cmd_lineno = irule->cmd_lineno;
418 *out_rule = r;
419 return true;
420 }
421 if (vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900422 CHECK(irule->outputs.size() == 1);
423 vars = MergeImplicitRuleVars(irule->outputs[0], vars);
424 *out_var = vars;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900425 }
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900426 *out_rule = irule;
427 return true;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900428 }
429
430 return rule.get();
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900431 }
432
Shinichiro Hamaji8d503012015-07-03 16:26:15 +0900433 DepNode* BuildPlan(Symbol output, Symbol needed_by UNUSED) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900434 LOG("BuildPlan: %s for %s",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900435 output.c_str(),
436 needed_by.c_str());
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900437
438 auto found = done_.find(output);
439 if (found != done_.end()) {
440 return found->second;
441 }
442
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900443 DepNode* n = new DepNode(output, phony_.count(output));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900444 done_[output] = n;
445
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900446 shared_ptr<Rule> rule;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900447 Vars* vars;
448 if (!PickRule(output, &rule, &vars)) {
449 return n;
450 }
451
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900452 if (rule->output_patterns.size() >= 1) {
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900453 if (rule->output_patterns.size() != 1) {
454 fprintf(stderr, "hmm %s\n", rule->DebugString().c_str());
455 }
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900456 CHECK(rule->output_patterns.size() == 1);
457 n->output_pattern = rule->output_patterns[0];
458 }
459
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900460 vector<unique_ptr<ScopedVar>> sv;
461 if (vars) {
462 for (const auto& p : *vars) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900463 Symbol name = p.first;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900464 RuleVar* var = reinterpret_cast<RuleVar*>(p.second);
465 CHECK(var);
466 Var* new_var = var->v();
467 if (var->op() == AssignOp::PLUS_EQ) {
468 Var* old_var = ev_->LookupVar(name);
469 if (old_var->IsDefined()) {
470 // TODO: This would be incorrect and has a leak.
471 shared_ptr<string> s = make_shared<string>();
472 old_var->Eval(ev_, s.get());
Shinichiro Hamaji3c785c72015-06-23 19:22:34 +0900473 if (!s->empty())
474 *s += ' ';
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900475 new_var->Eval(ev_, s.get());
Shinichiro Hamaji5081c712015-08-14 16:49:20 +0900476 new_var = new SimpleVar(*s, old_var->Origin());
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900477 }
478 } else if (var->op() == AssignOp::QUESTION_EQ) {
479 Var* old_var = ev_->LookupVar(name);
480 if (old_var->IsDefined()) {
481 continue;
482 }
483 }
Shinichiro Hamajie978a892015-08-17 16:53:40 +0900484 sv.emplace_back(new ScopedVar(cur_rule_vars_.get(), name, new_var));
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900485 }
486 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900487
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900488 ApplyOutputPattern(*rule, output, rule->inputs, &n->actual_inputs);
489 for (Symbol input : n->actual_inputs) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900490 DepNode* c = BuildPlan(input, output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900491 n->deps.push_back(c);
492 }
493
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900494 vector<Symbol> order_only_inputs;
495 ApplyOutputPattern(*rule, output, rule->order_only_inputs,
496 &order_only_inputs);
497 for (Symbol input : order_only_inputs) {
Shinichiro Hamaji704e4fe2015-06-24 17:37:47 +0900498 DepNode* c = BuildPlan(input, output);
Shinichiro Hamaji183dbb92015-07-06 17:21:39 +0900499 n->order_onlys.push_back(c);
Shinichiro Hamaji704e4fe2015-06-24 17:37:47 +0900500 }
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900501
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900502 n->has_rule = true;
503 n->cmds = rule->cmds;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900504 if (cur_rule_vars_->empty()) {
505 n->rule_vars = NULL;
506 } else {
507 n->rule_vars = new Vars;
508 for (auto p : *cur_rule_vars_) {
509 n->rule_vars->insert(p);
510 }
511 }
512 n->loc = rule->loc;
513 if (!rule->cmds.empty() && rule->cmd_lineno)
514 n->loc.lineno = rule->cmd_lineno;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900515
516 return n;
517 }
518
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900519 Evaluator* ev_;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900520 unordered_map<Symbol, shared_ptr<Rule>> rules_;
521 const unordered_map<Symbol, Vars*>& rule_vars_;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900522 unique_ptr<Vars> cur_rule_vars_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900523
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900524 unique_ptr<RuleTrie> implicit_rules_;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900525 typedef unordered_map<StringPiece, vector<shared_ptr<Rule>>> SuffixRuleMap;
526 SuffixRuleMap suffix_rules_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900527
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900528 shared_ptr<Rule> first_rule_;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900529 unordered_map<Symbol, DepNode*> done_;
530 unordered_set<Symbol> phony_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900531};
532
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900533void MakeDep(Evaluator* ev,
534 const vector<shared_ptr<Rule>>& rules,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900535 const unordered_map<Symbol, Vars*>& rule_vars,
536 const vector<Symbol>& targets,
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900537 vector<DepNode*>* nodes) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900538 DepBuilder db(ev, rules, rule_vars);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900539 db.Build(targets, nodes);
540}
541
542void InitDepNodePool() {
543 g_dep_node_pool = new vector<DepNode*>;
544}
545
546void QuitDepNodePool() {
547 for (DepNode* n : *g_dep_node_pool)
548 delete n;
549 delete g_dep_node_pool;
550}