| Index: tools/clang/blink_gc_plugin/RecordInfo.cpp
|
| diff --git a/tools/clang/blink_gc_plugin/RecordInfo.cpp b/tools/clang/blink_gc_plugin/RecordInfo.cpp
|
| index cd5263289a1cab84fedf470eb83af45593815efd..1bf954e5c5f7bcd37fe110de69c6a23b1d531c99 100644
|
| --- a/tools/clang/blink_gc_plugin/RecordInfo.cpp
|
| +++ b/tools/clang/blink_gc_plugin/RecordInfo.cpp
|
| @@ -19,6 +19,8 @@ RecordInfo::RecordInfo(CXXRecordDecl* record, RecordCache* cache)
|
| is_non_newable_(kNotComputed),
|
| is_only_placement_newable_(kNotComputed),
|
| does_need_finalization_(kNotComputed),
|
| + has_gc_mixin_methods_(kNotComputed),
|
| + is_declaring_local_trace_(kNotComputed),
|
| determined_trace_methods_(false),
|
| trace_method_(0),
|
| trace_dispatch_method_(0),
|
| @@ -309,6 +311,48 @@ CXXMethodDecl* RecordInfo::InheritsNonVirtualTrace() {
|
| return 0;
|
| }
|
|
|
| +bool RecordInfo::DeclaresGCMixinMethods() {
|
| + DetermineTracingMethods();
|
| + return has_gc_mixin_methods_;
|
| +}
|
| +
|
| +bool RecordInfo::DeclaresLocalTraceMethod() {
|
| + if (is_declaring_local_trace_ != kNotComputed)
|
| + return is_declaring_local_trace_;
|
| + DetermineTracingMethods();
|
| + is_declaring_local_trace_ = trace_method_ ? kTrue : kFalse;
|
| + if (is_declaring_local_trace_) {
|
| + for (auto it = record_->method_begin();
|
| + it != record_->method_end(); ++it) {
|
| + if (*it == trace_method_) {
|
| + is_declaring_local_trace_ = kTrue;
|
| + break;
|
| + }
|
| + }
|
| + }
|
| + return is_declaring_local_trace_;
|
| +}
|
| +
|
| +bool RecordInfo::IsGCMixinInstance() {
|
| + assert(IsGCDerived());
|
| + if (record_->isAbstract())
|
| + return false;
|
| +
|
| + assert(!IsGCMixin());
|
| +
|
| + // true iff the class derives from GCMixin and
|
| + // one or more other GC base classes.
|
| + bool seen_gc_mixin = false;
|
| + bool seen_gc_derived = false;
|
| + for (const auto& gc_base : gc_base_names_) {
|
| + if (Config::IsGCMixinBase(gc_base))
|
| + seen_gc_mixin = true;
|
| + else if (Config::IsGCBase(gc_base))
|
| + seen_gc_derived = true;
|
| + }
|
| + return seen_gc_derived && seen_gc_mixin;
|
| +}
|
| +
|
| // A (non-virtual) class is considered abstract in Blink if it has
|
| // no public constructors and no create methods.
|
| bool RecordInfo::IsConsideredAbstract() {
|
| @@ -385,6 +429,8 @@ void RecordInfo::DetermineTracingMethods() {
|
| CXXMethodDecl* trace = 0;
|
| CXXMethodDecl* traceAfterDispatch = 0;
|
| bool isTraceAfterDispatch;
|
| + bool hasAdjustAndMark = false;
|
| + bool hasIsHeapObjectAlive = false;
|
| for (CXXRecordDecl::method_iterator it = record_->method_begin();
|
| it != record_->method_end();
|
| ++it) {
|
| @@ -396,8 +442,15 @@ void RecordInfo::DetermineTracingMethods() {
|
| }
|
| } else if (it->getNameAsString() == kFinalizeName) {
|
| finalize_dispatch_method_ = *it;
|
| + } else if (it->getNameAsString() == kAdjustAndMarkName) {
|
| + hasAdjustAndMark = true;
|
| + } else if (it->getNameAsString() == kIsHeapObjectAliveName) {
|
| + hasIsHeapObjectAlive = true;
|
| }
|
| }
|
| + // Record if class defines the two GCMixin methods.
|
| + has_gc_mixin_methods_ =
|
| + hasAdjustAndMark && hasIsHeapObjectAlive ? kTrue : kFalse;
|
| if (traceAfterDispatch) {
|
| trace_method_ = traceAfterDispatch;
|
| trace_dispatch_method_ = trace;
|
|
|