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 025741519cb8e1946c3379dcaa378efb30d450aa..bda33fa992fb5cd92a907fcbb8d9b1c18c94a61b 100644 |
--- a/tools/clang/blink_gc_plugin/RecordInfo.cpp |
+++ b/tools/clang/blink_gc_plugin/RecordInfo.cpp |
@@ -427,39 +427,50 @@ void RecordInfo::DetermineTracingMethods() { |
if (Config::IsGCBase(name_)) |
return; |
CXXMethodDecl* trace = nullptr; |
+ CXXMethodDecl* trace_impl = nullptr; |
CXXMethodDecl* trace_after_dispatch = nullptr; |
bool has_adjust_and_mark = false; |
bool has_is_heap_object_alive = false; |
- for (CXXRecordDecl::method_iterator it = record_->method_begin(); |
- it != record_->method_end(); |
- ++it) { |
- switch (Config::GetTraceMethodType(*it)) { |
+ for (Decl* decl : record_->decls()) { |
+ CXXMethodDecl* method = dyn_cast<CXXMethodDecl>(decl); |
+ if (!method) { |
+ if (FunctionTemplateDecl* func_template = |
+ dyn_cast<FunctionTemplateDecl>(decl)) |
+ method = dyn_cast<CXXMethodDecl>(func_template->getTemplatedDecl()); |
+ } |
+ if (!method) |
+ continue; |
+ |
+ switch (Config::GetTraceMethodType(method)) { |
case Config::TRACE_METHOD: |
- trace = *it; |
+ trace = method; |
break; |
case Config::TRACE_AFTER_DISPATCH_METHOD: |
- trace_after_dispatch = *it; |
+ trace_after_dispatch = method; |
break; |
case Config::TRACE_IMPL_METHOD: |
+ trace_impl = method; |
+ break; |
case Config::TRACE_AFTER_DISPATCH_IMPL_METHOD: |
break; |
case Config::NOT_TRACE_METHOD: |
- if (it->getNameAsString() == kFinalizeName) { |
- finalize_dispatch_method_ = *it; |
- } else if (it->getNameAsString() == kAdjustAndMarkName) { |
+ if (method->getNameAsString() == kFinalizeName) { |
+ finalize_dispatch_method_ = method; |
+ } else if (method->getNameAsString() == kAdjustAndMarkName) { |
has_adjust_and_mark = true; |
- } else if (it->getNameAsString() == kIsHeapObjectAliveName) { |
+ } else if (method->getNameAsString() == kIsHeapObjectAliveName) { |
has_is_heap_object_alive = true; |
} |
break; |
} |
} |
+ |
// Record if class defines the two GCMixin methods. |
has_gc_mixin_methods_ = |
has_adjust_and_mark && has_is_heap_object_alive ? kTrue : kFalse; |
if (trace_after_dispatch) { |
trace_method_ = trace_after_dispatch; |
- trace_dispatch_method_ = trace; |
+ trace_dispatch_method_ = trace_impl ? trace_impl : trace; |
} else { |
// TODO: Can we never have a dispatch method called trace without the same |
// class defining a traceAfterDispatch method? |