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 ed1817d5576f54ca19317f9da29e014c9c920aa0..fe84dcc49ccc8f36b81ceb7d544fc7c92ccd3108 100644 |
--- a/tools/clang/blink_gc_plugin/RecordInfo.cpp |
+++ b/tools/clang/blink_gc_plugin/RecordInfo.cpp |
@@ -194,6 +194,34 @@ bool RecordInfo::InheritsNonPureTrace() { |
return false; |
} |
+CXXMethodDecl* RecordInfo::InheritsNonVirtualTrace() { |
+ if (CXXMethodDecl* trace = GetTraceMethod()) |
+ return trace->isVirtual() ? 0 : trace; |
+ for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { |
+ if (CXXMethodDecl* trace = it->second.info()->InheritsNonVirtualTrace()) |
+ return trace; |
+ } |
+ return 0; |
+} |
+ |
+// A (non-virtual) class is considered abstract in Blink if it has |
+// no public constructors and no create methods. |
+bool RecordInfo::IsConsideredAbstract() { |
+ for (CXXRecordDecl::ctor_iterator it = record_->ctor_begin(); |
+ it != record_->ctor_end(); |
+ ++it) { |
+ if (!it->isCopyOrMoveConstructor() && it->getAccess() == AS_public) |
+ return false; |
+ } |
+ for (CXXRecordDecl::method_iterator it = record_->method_begin(); |
+ it != record_->method_end(); |
+ ++it) { |
+ if (it->getNameAsString() == kCreateName) |
+ return false; |
+ } |
+ return true; |
+} |
+ |
RecordInfo::Bases* RecordInfo::CollectBases() { |
// Compute the collection locally to avoid inconsistent states. |
Bases* bases = new Bases; |
@@ -254,7 +282,6 @@ void RecordInfo::DetermineTracingMethods() { |
it != record_->method_end(); |
++it) { |
if (Config::IsTraceMethod(*it, &isTraceAfterDispatch)) { |
- // TODO: Test that the formal parameter is of type Visitor*. |
if (isTraceAfterDispatch) { |
traceAfterDispatch = *it; |
} else { |
@@ -271,6 +298,16 @@ void RecordInfo::DetermineTracingMethods() { |
trace_method_ = trace; |
trace_dispatch_method_ = 0; |
} |
+ if (trace_dispatch_method_) |
+ return; |
Mads Ager (chromium)
2014/03/18 09:19:32
How about removing this and instead moving the bel
zerny-chromium
2014/03/18 10:03:41
The for loop might need to run in either branch si
|
+ // If this class does not define a trace dispatch method search inherit it. |
Mads Ager (chromium)
2014/03/18 09:19:32
search the inheritance hierarchy for it?
zerny-chromium
2014/03/18 10:03:41
Yes. Thanks.
|
+ for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { |
+ if (CXXMethodDecl* dispatch = it->second.info()->GetTraceDispatchMethod()) { |
+ // TODO: Does it make sense to inherit multiple dispatch methods? |
+ assert(!trace_dispatch_method_ && "Multiple trace dispatching methods"); |
+ trace_dispatch_method_ = dispatch; |
+ } |
+ } |
} |
// TODO: Add classes with a finalize() method that specialize FinalizerTrait. |