OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "Config.h" | 5 #include "Config.h" |
6 #include "RecordInfo.h" | 6 #include "RecordInfo.h" |
7 | 7 |
8 using namespace clang; | 8 using namespace clang; |
9 using std::string; | 9 using std::string; |
10 | 10 |
11 RecordInfo::RecordInfo(CXXRecordDecl* record, RecordCache* cache) | 11 RecordInfo::RecordInfo(CXXRecordDecl* record, RecordCache* cache) |
12 : cache_(cache), | 12 : cache_(cache), |
13 record_(record), | 13 record_(record), |
14 name_(record->getName()), | 14 name_(record->getName()), |
15 fields_need_tracing_(TracingStatus::Unknown()), | 15 fields_need_tracing_(TracingStatus::Unknown()), |
16 bases_(0), | 16 bases_(0), |
17 fields_(0), | 17 fields_(0), |
18 is_stack_allocated_(kNotComputed), | 18 is_stack_allocated_(kNotComputed), |
19 is_non_newable_(kNotComputed), | 19 is_non_newable_(kNotComputed), |
20 is_only_placement_newable_(kNotComputed), | 20 is_only_placement_newable_(kNotComputed), |
21 does_need_finalization_(kNotComputed), | |
21 determined_trace_methods_(false), | 22 determined_trace_methods_(false), |
22 trace_method_(0), | 23 trace_method_(0), |
23 trace_dispatch_method_(0), | 24 trace_dispatch_method_(0), |
24 finalize_dispatch_method_(0), | 25 finalize_dispatch_method_(0), |
25 is_gc_derived_(false), | 26 is_gc_derived_(false), |
26 base_paths_(0) {} | 27 base_paths_(0) {} |
27 | 28 |
28 RecordInfo::~RecordInfo() { | 29 RecordInfo::~RecordInfo() { |
29 delete fields_; | 30 delete fields_; |
30 delete bases_; | 31 delete bases_; |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
393 it->second.info()->GetFinalizeDispatchMethod()) { | 394 it->second.info()->GetFinalizeDispatchMethod()) { |
394 assert(!finalize_dispatch_method_ && | 395 assert(!finalize_dispatch_method_ && |
395 "Multiple finalize dispatching methods"); | 396 "Multiple finalize dispatching methods"); |
396 finalize_dispatch_method_ = dispatch; | 397 finalize_dispatch_method_ = dispatch; |
397 } | 398 } |
398 } | 399 } |
399 } | 400 } |
400 | 401 |
401 // TODO: Add classes with a finalize() method that specialize FinalizerTrait. | 402 // TODO: Add classes with a finalize() method that specialize FinalizerTrait. |
402 bool RecordInfo::NeedsFinalization() { | 403 bool RecordInfo::NeedsFinalization() { |
403 return record_->hasNonTrivialDestructor(); | 404 if (does_need_finalization_ == kNotComputed) { |
405 // Rely on hasNonTrivialDestructor(), but if the only | |
406 // identifiable reason why it is true is the presence | |
407 // of a class with a safely ignorable class as a direct base, | |
408 // or such a class is being represented here, then it does | |
409 // not need finalization. | |
410 does_need_finalization_ = | |
411 record_->hasNonTrivialDestructor() ? kTrue : kFalse; | |
412 if (does_need_finalization_) { | |
zerny-chromium
2014/07/08 07:45:03
Add early exit instead:
if (!does_need_finalizati
sof
2014/07/08 08:47:05
Rephrased to use early returns instead of fallthro
| |
413 // Checking if processing a class with a safely-ignorable destructor. | |
414 NamespaceDecl* ns = | |
415 dyn_cast<NamespaceDecl>(record_->getDeclContext()); | |
416 if (ns && Config::HasIgnorableDestructor(ns->getName(), name_)) | |
417 does_need_finalization_ = kFalse; | |
zerny-chromium
2014/07/08 07:45:02
Do an early return in this block as well and avoid
| |
418 } | |
419 if (does_need_finalization_) { | |
420 CXXDestructorDecl* dtor = record_->getDestructor(); | |
421 bool is_candidate = !dtor || !dtor->isUserProvided(); | |
422 for (Fields::iterator it = GetFields().begin(); | |
423 is_candidate && it != GetFields().end(); | |
424 ++it) { | |
425 if (it->second.edge()->NeedsFinalization()) | |
426 is_candidate = false; | |
zerny-chromium
2014/07/08 07:45:03
This can just return does_need_finalization_ which
| |
427 } | |
428 | |
429 for (Bases::iterator it = GetBases().begin(); | |
430 is_candidate && it != GetBases().end(); | |
431 ++it) { | |
432 NamespaceDecl* ns = dyn_cast<NamespaceDecl>( | |
433 it->second.info()->record()->getDeclContext()); | |
434 if (ns && | |
zerny-chromium
2014/07/08 07:45:03
This check is not be needed here. The ignored case
sof
2014/07/08 08:47:05
I was hesitant to remove it, in case the complete
sof
2014/07/08 08:48:49
s/in case/in scope/. Need more coffee.
| |
435 Config::HasIgnorableDestructor(ns->getName(), | |
436 it->second.info()->name())) | |
437 continue; | |
438 if (it->second.info()->NeedsFinalization()) | |
439 is_candidate = false; | |
zerny-chromium
2014/07/08 07:45:02
Just return does_need_finalization_
| |
440 } | |
441 if (is_candidate) | |
zerny-chromium
2014/07/08 07:45:02
Here we can unconditionally set does_need_finaliza
| |
442 does_need_finalization_ = kFalse; | |
443 } | |
444 } | |
445 return does_need_finalization_; | |
404 } | 446 } |
405 | 447 |
406 // A class needs tracing if: | 448 // A class needs tracing if: |
407 // - it is allocated on the managed heap, | 449 // - it is allocated on the managed heap, |
408 // - it is derived from a class that needs tracing, or | 450 // - it is derived from a class that needs tracing, or |
409 // - it contains fields that need tracing. | 451 // - it contains fields that need tracing. |
410 // TODO: Defining NeedsTracing based on whether a class defines a trace method | 452 // TODO: Defining NeedsTracing based on whether a class defines a trace method |
411 // (of the proper signature) over approximates too much. The use of transition | 453 // (of the proper signature) over approximates too much. The use of transition |
412 // types causes some classes to have trace methods without them needing to be | 454 // types causes some classes to have trace methods without them needing to be |
413 // traced. | 455 // traced. |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
506 edge->members().push_back(member); | 548 edge->members().push_back(member); |
507 } | 549 } |
508 // TODO: Handle the case where we fail to create an edge (eg, if the | 550 // TODO: Handle the case where we fail to create an edge (eg, if the |
509 // argument is a primitive type or just not fully known yet). | 551 // argument is a primitive type or just not fully known yet). |
510 } | 552 } |
511 return edge; | 553 return edge; |
512 } | 554 } |
513 | 555 |
514 return new Value(info); | 556 return new Value(info); |
515 } | 557 } |
OLD | NEW |