| 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 |
| (...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 // Rely on hasNonTrivialDestructor(), but if the only | 503 // Rely on hasNonTrivialDestructor(), but if the only |
| 504 // identifiable reason for it being true is the presence | 504 // identifiable reason for it being true is the presence |
| 505 // of a safely ignorable class as a direct base, | 505 // of a safely ignorable class as a direct base, |
| 506 // or we're processing such an 'ignorable' class, then it does | 506 // or we're processing such an 'ignorable' class, then it does |
| 507 // not need finalization. | 507 // not need finalization. |
| 508 does_need_finalization_ = | 508 does_need_finalization_ = |
| 509 record_->hasNonTrivialDestructor() ? kTrue : kFalse; | 509 record_->hasNonTrivialDestructor() ? kTrue : kFalse; |
| 510 if (!does_need_finalization_) | 510 if (!does_need_finalization_) |
| 511 return does_need_finalization_; | 511 return does_need_finalization_; |
| 512 | 512 |
| 513 // Processing a class with a safely-ignorable destructor. | |
| 514 NamespaceDecl* ns = | |
| 515 dyn_cast<NamespaceDecl>(record_->getDeclContext()); | |
| 516 if (ns && Config::HasIgnorableDestructor(ns->getName(), name_)) { | |
| 517 does_need_finalization_ = kFalse; | |
| 518 return does_need_finalization_; | |
| 519 } | |
| 520 | |
| 521 CXXDestructorDecl* dtor = record_->getDestructor(); | 513 CXXDestructorDecl* dtor = record_->getDestructor(); |
| 522 if (dtor && dtor->isUserProvided()) | 514 if (dtor && dtor->isUserProvided()) |
| 523 return does_need_finalization_; | 515 return does_need_finalization_; |
| 524 for (Fields::iterator it = GetFields().begin(); | 516 for (Fields::iterator it = GetFields().begin(); |
| 525 it != GetFields().end(); | 517 it != GetFields().end(); |
| 526 ++it) { | 518 ++it) { |
| 527 if (it->second.edge()->NeedsFinalization()) | 519 if (it->second.edge()->NeedsFinalization()) |
| 528 return does_need_finalization_; | 520 return does_need_finalization_; |
| 529 } | 521 } |
| 530 | 522 |
| 531 for (Bases::iterator it = GetBases().begin(); | 523 for (Bases::iterator it = GetBases().begin(); |
| 532 it != GetBases().end(); | 524 it != GetBases().end(); |
| 533 ++it) { | 525 ++it) { |
| 534 if (it->second.info()->NeedsFinalization()) | 526 if (it->second.info()->NeedsFinalization()) |
| 535 return does_need_finalization_; | 527 return does_need_finalization_; |
| 536 } | 528 } |
| 537 // Destructor was non-trivial due to bases with destructors that | 529 // Destructor was non-trivial due to bases with destructors that |
| 538 // can be safely ignored. Hence, no need for finalization. | 530 // can be safely ignored. Hence, no need for finalization. |
| 539 does_need_finalization_ = kFalse; | 531 does_need_finalization_ = kFalse; |
| 540 } | 532 } |
| 541 return does_need_finalization_; | 533 return does_need_finalization_; |
| 542 } | 534 } |
| 543 | 535 |
| 544 // A class needs tracing if: | 536 // A class needs tracing if: |
| 545 // - it is allocated on the managed heap, | 537 // - it is allocated on the managed heap, |
| 546 // - it is derived from a class that needs tracing, or | 538 // - it is derived from a class that needs tracing, or |
| 547 // - it contains fields that need tracing. | 539 // - it contains fields that need tracing. |
| 548 // TODO: Defining NeedsTracing based on whether a class defines a trace method | 540 // |
| 549 // (of the proper signature) over approximates too much. The use of transition | |
| 550 // types causes some classes to have trace methods without them needing to be | |
| 551 // traced. | |
| 552 TracingStatus RecordInfo::NeedsTracing(Edge::NeedsTracingOption option) { | 541 TracingStatus RecordInfo::NeedsTracing(Edge::NeedsTracingOption option) { |
| 553 if (IsGCAllocated()) | 542 if (IsGCAllocated()) |
| 554 return TracingStatus::Needed(); | 543 return TracingStatus::Needed(); |
| 555 | 544 |
| 556 if (IsStackAllocated()) | 545 if (IsStackAllocated()) |
| 557 return TracingStatus::Unneeded(); | 546 return TracingStatus::Unneeded(); |
| 558 | 547 |
| 559 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { | 548 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { |
| 560 if (it->second.info()->NeedsTracing(option).IsNeeded()) | 549 if (it->second.info()->NeedsTracing(option).IsNeeded()) |
| 561 return TracingStatus::Needed(); | 550 return TracingStatus::Needed(); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 edge->members().push_back(member); | 627 edge->members().push_back(member); |
| 639 } | 628 } |
| 640 // TODO: Handle the case where we fail to create an edge (eg, if the | 629 // TODO: Handle the case where we fail to create an edge (eg, if the |
| 641 // argument is a primitive type or just not fully known yet). | 630 // argument is a primitive type or just not fully known yet). |
| 642 } | 631 } |
| 643 return edge; | 632 return edge; |
| 644 } | 633 } |
| 645 | 634 |
| 646 return new Value(info); | 635 return new Value(info); |
| 647 } | 636 } |
| OLD | NEW |