Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: tools/gn/builder.cc

Issue 610293003: Replace more for loops in GN (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: review Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/gn/binary_target_generator.cc ('k') | tools/gn/command_args.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "tools/gn/builder.h" 5 #include "tools/gn/builder.h"
6 6
7 #include "tools/gn/config.h" 7 #include "tools/gn/config.h"
8 #include "tools/gn/deps_iterator.h" 8 #include "tools/gn/deps_iterator.h"
9 #include "tools/gn/err.h" 9 #include "tools/gn/err.h"
10 #include "tools/gn/loader.h" 10 #include "tools/gn/loader.h"
(...skipping 11 matching lines...) Expand all
22 // participates in a cycle. 22 // participates in a cycle.
23 // 23 //
24 // If this returns true, the cycle will be in *path. This should point to an 24 // If this returns true, the cycle will be in *path. This should point to an
25 // empty vector for the first call. During computation, the path will contain 25 // empty vector for the first call. During computation, the path will contain
26 // the full dependency path to the current node. 26 // the full dependency path to the current node.
27 // 27 //
28 // Return false means no cycle was found. 28 // Return false means no cycle was found.
29 bool RecursiveFindCycle(const BuilderRecord* search_in, 29 bool RecursiveFindCycle(const BuilderRecord* search_in,
30 std::vector<const BuilderRecord*>* path) { 30 std::vector<const BuilderRecord*>* path) {
31 path->push_back(search_in); 31 path->push_back(search_in);
32 32 for (const auto& cur : search_in->unresolved_deps()) {
33 const BuilderRecord::BuilderRecordSet& unresolved =
34 search_in->unresolved_deps();
35 for (BuilderRecord::BuilderRecordSet::const_iterator i = unresolved.begin();
36 i != unresolved.end(); ++i) {
37 const BuilderRecord* cur = *i;
38
39 std::vector<const BuilderRecord*>::iterator found = 33 std::vector<const BuilderRecord*>::iterator found =
40 std::find(path->begin(), path->end(), cur); 34 std::find(path->begin(), path->end(), cur);
41 if (found != path->end()) { 35 if (found != path->end()) {
42 // This item is already in the set, we found the cycle. Everything before 36 // This item is already in the set, we found the cycle. Everything before
43 // the first definition of cur is irrelevant to the cycle. 37 // the first definition of cur is irrelevant to the cycle.
44 path->erase(path->begin(), found); 38 path->erase(path->begin(), found);
45 path->push_back(cur); 39 path->push_back(cur);
46 return true; 40 return true;
47 } 41 }
48 42
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 if (!record) 119 if (!record)
126 return NULL; 120 return NULL;
127 if (!record->item()) 121 if (!record->item())
128 return NULL; 122 return NULL;
129 return record->item()->AsToolchain(); 123 return record->item()->AsToolchain();
130 } 124 }
131 125
132 std::vector<const BuilderRecord*> Builder::GetAllRecords() const { 126 std::vector<const BuilderRecord*> Builder::GetAllRecords() const {
133 std::vector<const BuilderRecord*> result; 127 std::vector<const BuilderRecord*> result;
134 result.reserve(records_.size()); 128 result.reserve(records_.size());
135 for (RecordMap::const_iterator i = records_.begin(); 129 for (const auto& record : records_)
136 i != records_.end(); ++i) 130 result.push_back(record.second);
137 result.push_back(i->second);
138 return result; 131 return result;
139 } 132 }
140 133
141 std::vector<const Target*> Builder::GetAllResolvedTargets() const { 134 std::vector<const Target*> Builder::GetAllResolvedTargets() const {
142 std::vector<const Target*> result; 135 std::vector<const Target*> result;
143 result.reserve(records_.size()); 136 result.reserve(records_.size());
144 for (RecordMap::const_iterator i = records_.begin(); 137 for (const auto& record : records_) {
145 i != records_.end(); ++i) { 138 if (record.second->type() == BuilderRecord::ITEM_TARGET &&
146 if (i->second->type() == BuilderRecord::ITEM_TARGET && 139 record.second->should_generate() && record.second->item())
147 i->second->should_generate() && i->second->item()) 140 result.push_back(record.second->item()->AsTarget());
148 result.push_back(i->second->item()->AsTarget());
149 } 141 }
150 return result; 142 return result;
151 } 143 }
152 144
153 const BuilderRecord* Builder::GetRecord(const Label& label) const { 145 const BuilderRecord* Builder::GetRecord(const Label& label) const {
154 // Forward to the non-const version. 146 // Forward to the non-const version.
155 return const_cast<Builder*>(this)->GetRecord(label); 147 return const_cast<Builder*>(this)->GetRecord(label);
156 } 148 }
157 149
158 BuilderRecord* Builder::GetRecord(const Label& label) { 150 BuilderRecord* Builder::GetRecord(const Label& label) {
159 RecordMap::iterator found = records_.find(label); 151 RecordMap::iterator found = records_.find(label);
160 if (found == records_.end()) 152 if (found == records_.end())
161 return NULL; 153 return NULL;
162 return found->second; 154 return found->second;
163 } 155 }
164 156
165 bool Builder::CheckForBadItems(Err* err) const { 157 bool Builder::CheckForBadItems(Err* err) const {
166 // Look for errors where we find a defined node with an item that refers to 158 // Look for errors where we find a defined node with an item that refers to
167 // an undefined one with no item. There may be other nodes in turn depending 159 // an undefined one with no item. There may be other nodes in turn depending
168 // on our defined one, but listing those isn't helpful: we want to find the 160 // on our defined one, but listing those isn't helpful: we want to find the
169 // broken link. 161 // broken link.
170 // 162 //
171 // This finds normal "missing dependency" errors but does not find circular 163 // This finds normal "missing dependency" errors but does not find circular
172 // dependencies because in this case all items in the cycle will be GENERATED 164 // dependencies because in this case all items in the cycle will be GENERATED
173 // but none will be resolved. If this happens, we'll check explicitly for 165 // but none will be resolved. If this happens, we'll check explicitly for
174 // that below. 166 // that below.
175 std::vector<const BuilderRecord*> bad_records; 167 std::vector<const BuilderRecord*> bad_records;
176 std::string depstring; 168 std::string depstring;
177 for (RecordMap::const_iterator i = records_.begin(); 169 for (const auto& record_pair : records_) {
178 i != records_.end(); ++i) { 170 const BuilderRecord* src = record_pair.second;
179 const BuilderRecord* src = i->second;
180 if (!src->should_generate()) 171 if (!src->should_generate())
181 continue; // Skip ungenerated nodes. 172 continue; // Skip ungenerated nodes.
182 173
183 if (!src->resolved()) { 174 if (!src->resolved()) {
184 bad_records.push_back(src); 175 bad_records.push_back(src);
185 176
186 // Check dependencies. 177 // Check dependencies.
187 for (BuilderRecord::BuilderRecordSet::const_iterator dest_iter = 178 for (const auto& dest : src->unresolved_deps()) {
188 src->unresolved_deps().begin();
189 dest_iter != src->unresolved_deps().end();
190 ++dest_iter) {
191 const BuilderRecord* dest = *dest_iter;
192 if (!dest->item()) { 179 if (!dest->item()) {
193 depstring += src->label().GetUserVisibleName(true) + 180 depstring += src->label().GetUserVisibleName(true) +
194 "\n needs " + dest->label().GetUserVisibleName(true) + "\n"; 181 "\n needs " + dest->label().GetUserVisibleName(true) + "\n";
195 } 182 }
196 } 183 }
197 } 184 }
198 } 185 }
199 186
200 if (!depstring.empty()) { 187 if (!depstring.empty()) {
201 *err = Err(Location(), "Unresolved dependencies.", depstring); 188 *err = Err(Location(), "Unresolved dependencies.", depstring);
202 return false; 189 return false;
203 } 190 }
204 191
205 if (!bad_records.empty()) { 192 if (!bad_records.empty()) {
206 // Our logic above found a bad node but didn't identify the problem. This 193 // Our logic above found a bad node but didn't identify the problem. This
207 // normally means a circular dependency. 194 // normally means a circular dependency.
208 depstring = CheckForCircularDependencies(bad_records); 195 depstring = CheckForCircularDependencies(bad_records);
209 if (depstring.empty()) { 196 if (depstring.empty()) {
210 // Something's very wrong, just dump out the bad nodes. 197 // Something's very wrong, just dump out the bad nodes.
211 depstring = "I have no idea what went wrong, but these are unresolved, " 198 depstring = "I have no idea what went wrong, but these are unresolved, "
212 "possibly due to an\ninternal error:"; 199 "possibly due to an\ninternal error:";
213 for (size_t i = 0; i < bad_records.size(); i++) { 200 for (const auto& bad_record : bad_records) {
214 depstring += "\n\"" + 201 depstring += "\n\"" +
215 bad_records[i]->label().GetUserVisibleName(false) + "\""; 202 bad_record->label().GetUserVisibleName(false) + "\"";
216 } 203 }
217 *err = Err(Location(), "", depstring); 204 *err = Err(Location(), "", depstring);
218 } else { 205 } else {
219 *err = Err(Location(), "Dependency cycle:", depstring); 206 *err = Err(Location(), "Dependency cycle:", depstring);
220 } 207 }
221 return false; 208 return false;
222 } 209 }
223 210
224 return true; 211 return true;
225 } 212 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 item->GetItemTypeName() + " instead of a " + 308 item->GetItemTypeName() + " instead of a " +
322 BuilderRecord::GetNameForType(type) + "."); 309 BuilderRecord::GetNameForType(type) + ".");
323 return NULL; 310 return NULL;
324 } 311 }
325 return record; 312 return record;
326 } 313 }
327 314
328 bool Builder::AddDeps(BuilderRecord* record, 315 bool Builder::AddDeps(BuilderRecord* record,
329 const LabelConfigVector& configs, 316 const LabelConfigVector& configs,
330 Err* err) { 317 Err* err) {
331 for (size_t i = 0; i < configs.size(); i++) { 318 for (const auto& config : configs) {
332 BuilderRecord* dep_record = GetOrCreateRecordOfType( 319 BuilderRecord* dep_record = GetOrCreateRecordOfType(
333 configs[i].label, configs[i].origin, BuilderRecord::ITEM_CONFIG, err); 320 config.label, config.origin, BuilderRecord::ITEM_CONFIG, err);
334 if (!dep_record) 321 if (!dep_record)
335 return false; 322 return false;
336 record->AddDep(dep_record); 323 record->AddDep(dep_record);
337 } 324 }
338 return true; 325 return true;
339 } 326 }
340 327
341 bool Builder::AddDeps(BuilderRecord* record, 328 bool Builder::AddDeps(BuilderRecord* record,
342 const UniqueVector<LabelConfigPair>& configs, 329 const UniqueVector<LabelConfigPair>& configs,
343 Err* err) { 330 Err* err) {
344 for (size_t i = 0; i < configs.size(); i++) { 331 for (const auto& config : configs) {
345 BuilderRecord* dep_record = GetOrCreateRecordOfType( 332 BuilderRecord* dep_record = GetOrCreateRecordOfType(
346 configs[i].label, configs[i].origin, BuilderRecord::ITEM_CONFIG, err); 333 config.label, config.origin, BuilderRecord::ITEM_CONFIG, err);
347 if (!dep_record) 334 if (!dep_record)
348 return false; 335 return false;
349 record->AddDep(dep_record); 336 record->AddDep(dep_record);
350 } 337 }
351 return true; 338 return true;
352 } 339 }
353 340
354 bool Builder::AddDeps(BuilderRecord* record, 341 bool Builder::AddDeps(BuilderRecord* record,
355 const LabelTargetVector& targets, 342 const LabelTargetVector& targets,
356 Err* err) { 343 Err* err) {
357 for (size_t i = 0; i < targets.size(); i++) { 344 for (const auto& target : targets) {
358 BuilderRecord* dep_record = GetOrCreateRecordOfType( 345 BuilderRecord* dep_record = GetOrCreateRecordOfType(
359 targets[i].label, targets[i].origin, BuilderRecord::ITEM_TARGET, err); 346 target.label, target.origin, BuilderRecord::ITEM_TARGET, err);
360 if (!dep_record) 347 if (!dep_record)
361 return false; 348 return false;
362 record->AddDep(dep_record); 349 record->AddDep(dep_record);
363 } 350 }
364 return true; 351 return true;
365 } 352 }
366 353
367 bool Builder::AddToolchainDep(BuilderRecord* record, 354 bool Builder::AddToolchainDep(BuilderRecord* record,
368 const Target* target, 355 const Target* target,
369 Err* err) { 356 Err* err) {
370 BuilderRecord* toolchain_record = GetOrCreateRecordOfType( 357 BuilderRecord* toolchain_record = GetOrCreateRecordOfType(
371 target->settings()->toolchain_label(), target->defined_from(), 358 target->settings()->toolchain_label(), target->defined_from(),
372 BuilderRecord::ITEM_TOOLCHAIN, err); 359 BuilderRecord::ITEM_TOOLCHAIN, err);
373 if (!toolchain_record) 360 if (!toolchain_record)
374 return false; 361 return false;
375 record->AddDep(toolchain_record); 362 record->AddDep(toolchain_record);
376 363
377 return true; 364 return true;
378 } 365 }
379 366
380 void Builder::RecursiveSetShouldGenerate(BuilderRecord* record, 367 void Builder::RecursiveSetShouldGenerate(BuilderRecord* record,
381 bool force) { 368 bool force) {
382 if (!force && record->should_generate()) 369 if (!force && record->should_generate())
383 return; // Already set. 370 return; // Already set.
384 record->set_should_generate(true); 371 record->set_should_generate(true);
385 372
386 const BuilderRecordSet& deps = record->all_deps(); 373 for (const auto& cur : record->all_deps()) {
387 for (BuilderRecordSet::const_iterator i = deps.begin();
388 i != deps.end(); i++) {
389 BuilderRecord* cur = *i;
390 if (!cur->should_generate()) { 374 if (!cur->should_generate()) {
391 ScheduleItemLoadIfNecessary(cur); 375 ScheduleItemLoadIfNecessary(cur);
392 RecursiveSetShouldGenerate(cur, false); 376 RecursiveSetShouldGenerate(cur, false);
393 } 377 }
394 } 378 }
395 } 379 }
396 380
397 void Builder::ScheduleItemLoadIfNecessary(BuilderRecord* record) { 381 void Builder::ScheduleItemLoadIfNecessary(BuilderRecord* record) {
398 const ParseNode* origin = record->originally_referenced_from(); 382 const ParseNode* origin = record->originally_referenced_from();
399 loader_->Load(record->label(), 383 loader_->Load(record->label(),
(...skipping 21 matching lines...) Expand all
421 } 405 }
422 406
423 record->set_resolved(true); 407 record->set_resolved(true);
424 408
425 if (!record->item()->OnResolved(err)) 409 if (!record->item()->OnResolved(err))
426 return false; 410 return false;
427 if (!resolved_callback_.is_null()) 411 if (!resolved_callback_.is_null())
428 resolved_callback_.Run(record); 412 resolved_callback_.Run(record);
429 413
430 // Recursively update everybody waiting on this item to be resolved. 414 // Recursively update everybody waiting on this item to be resolved.
431 BuilderRecordSet& waiting_set = record->waiting_on_resolution(); 415 for (BuilderRecord* waiting : record->waiting_on_resolution()) {
432 for (BuilderRecordSet::iterator i = waiting_set.begin();
433 i != waiting_set.end(); ++i) {
434 BuilderRecord* waiting = *i;
435 DCHECK(waiting->unresolved_deps().find(record) != 416 DCHECK(waiting->unresolved_deps().find(record) !=
436 waiting->unresolved_deps().end()); 417 waiting->unresolved_deps().end());
437 waiting->unresolved_deps().erase(record); 418 waiting->unresolved_deps().erase(record);
438 419
439 if (waiting->can_resolve()) { 420 if (waiting->can_resolve()) {
440 if (!ResolveItem(waiting, err)) 421 if (!ResolveItem(waiting, err))
441 return false; 422 return false;
442 } 423 }
443 } 424 }
444 waiting_set.clear(); 425 record->waiting_on_resolution().clear();
445 return true; 426 return true;
446 } 427 }
447 428
448 bool Builder::ResolveDeps(LabelTargetVector* deps, Err* err) { 429 bool Builder::ResolveDeps(LabelTargetVector* deps, Err* err) {
449 for (size_t i = 0; i < deps->size(); i++) { 430 for (LabelTargetPair& cur : *deps) {
450 LabelTargetPair& cur = (*deps)[i];
451 DCHECK(!cur.ptr); 431 DCHECK(!cur.ptr);
452 432
453 BuilderRecord* record = GetResolvedRecordOfType( 433 BuilderRecord* record = GetResolvedRecordOfType(
454 cur.label, cur.origin, BuilderRecord::ITEM_TARGET, err); 434 cur.label, cur.origin, BuilderRecord::ITEM_TARGET, err);
455 if (!record) 435 if (!record)
456 return false; 436 return false;
457 cur.ptr = record->item()->AsTarget(); 437 cur.ptr = record->item()->AsTarget();
458 } 438 }
459 return true; 439 return true;
460 } 440 }
461 441
462 bool Builder::ResolveConfigs(UniqueVector<LabelConfigPair>* configs, Err* err) { 442 bool Builder::ResolveConfigs(UniqueVector<LabelConfigPair>* configs, Err* err) {
463 for (size_t i = 0; i < configs->size(); i++) { 443 for (const auto& cur : *configs) {
464 const LabelConfigPair& cur = (*configs)[i];
465 DCHECK(!cur.ptr); 444 DCHECK(!cur.ptr);
466 445
467 BuilderRecord* record = GetResolvedRecordOfType( 446 BuilderRecord* record = GetResolvedRecordOfType(
468 cur.label, cur.origin, BuilderRecord::ITEM_CONFIG, err); 447 cur.label, cur.origin, BuilderRecord::ITEM_CONFIG, err);
469 if (!record) 448 if (!record)
470 return false; 449 return false;
471 const_cast<LabelConfigPair&>(cur).ptr = record->item()->AsConfig(); 450 const_cast<LabelConfigPair&>(cur).ptr = record->item()->AsConfig();
472 } 451 }
473 return true; 452 return true;
474 } 453 }
475 454
476 // "Forward dependent configs" should refer to targets in the deps that should 455 // "Forward dependent configs" should refer to targets in the deps that should
477 // have their configs forwarded. 456 // have their configs forwarded.
478 bool Builder::ResolveForwardDependentConfigs(Target* target, Err* err) { 457 bool Builder::ResolveForwardDependentConfigs(Target* target, Err* err) {
479 const UniqueVector<LabelTargetPair>& configs = 458 const UniqueVector<LabelTargetPair>& configs =
480 target->forward_dependent_configs(); 459 target->forward_dependent_configs();
481 460
482 // Assume that the lists are small so that brute-force n^2 is appropriate. 461 // Assume that the lists are small so that brute-force n^2 is appropriate.
483 for (size_t config_i = 0; config_i < configs.size(); config_i++) { 462 for (const auto& config : configs) {
484 for (const auto& dep_pair : target->GetDeps(Target::DEPS_LINKED)) { 463 for (const auto& dep_pair : target->GetDeps(Target::DEPS_LINKED)) {
485 if (configs[config_i].label == dep_pair.label) { 464 if (config.label == dep_pair.label) {
486 DCHECK(dep_pair.ptr); // Should already be resolved. 465 DCHECK(dep_pair.ptr); // Should already be resolved.
487 // UniqueVector's contents are constant so uniqueness is preserved, but 466 // UniqueVector's contents are constant so uniqueness is preserved, but
488 // we want to update this pointer which doesn't change uniqueness 467 // we want to update this pointer which doesn't change uniqueness
489 // (uniqueness in this vector is determined by the label only). 468 // (uniqueness in this vector is determined by the label only).
490 const_cast<LabelTargetPair&>(configs[config_i]).ptr = dep_pair.ptr; 469 const_cast<LabelTargetPair&>(config).ptr = dep_pair.ptr;
491 break; 470 break;
492 } 471 }
493 } 472 }
494 if (!configs[config_i].ptr) { 473 if (!config.ptr) {
495 *err = Err(target->defined_from(), 474 *err = Err(target->defined_from(),
496 "Target in forward_dependent_configs_from was not listed in the deps", 475 "Target in forward_dependent_configs_from was not listed in the deps",
497 "This target has a forward_dependent_configs_from entry that was " 476 "This target has a forward_dependent_configs_from entry that was "
498 "not present in\nthe deps. A target can only forward things it " 477 "not present in\nthe deps. A target can only forward things it "
499 "depends on. It was forwarding:\n " + 478 "depends on. It was forwarding:\n " +
500 configs[config_i].label.GetUserVisibleName(false)); 479 config.label.GetUserVisibleName(false));
501 return false; 480 return false;
502 } 481 }
503 } 482 }
504 return true; 483 return true;
505 } 484 }
506 485
507 bool Builder::ResolveToolchain(Target* target, Err* err) { 486 bool Builder::ResolveToolchain(Target* target, Err* err) {
508 BuilderRecord* record = GetResolvedRecordOfType( 487 BuilderRecord* record = GetResolvedRecordOfType(
509 target->settings()->toolchain_label(), target->defined_from(), 488 target->settings()->toolchain_label(), target->defined_from(),
510 BuilderRecord::ITEM_TOOLCHAIN, err); 489 BuilderRecord::ITEM_TOOLCHAIN, err);
(...skipping 20 matching lines...) Expand all
531 std::string ret; 510 std::string ret;
532 for (size_t i = 0; i < cycle.size(); i++) { 511 for (size_t i = 0; i < cycle.size(); i++) {
533 ret += " " + cycle[i]->label().GetUserVisibleName(false); 512 ret += " " + cycle[i]->label().GetUserVisibleName(false);
534 if (i != cycle.size() - 1) 513 if (i != cycle.size() - 1)
535 ret += " ->"; 514 ret += " ->";
536 ret += "\n"; 515 ret += "\n";
537 } 516 }
538 517
539 return ret; 518 return ret;
540 } 519 }
OLDNEW
« no previous file with comments | « tools/gn/binary_target_generator.cc ('k') | tools/gn/command_args.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698