Index: tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp |
diff --git a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp |
index d24d67ade4ff4c37aa2016b8d4d76567ea422652..1e407c9df482ddddb7d08d075ac4d3a43189dede 100644 |
--- a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp |
+++ b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp |
@@ -322,7 +322,9 @@ class CheckDispatchVisitor : public RecursiveASTVisitor<CheckDispatchVisitor> { |
class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> { |
public: |
CheckTraceVisitor(CXXMethodDecl* trace, RecordInfo* info) |
- : trace_(trace), info_(info) {} |
+ : trace_(trace), info_(info), delegates_to_traceimpl_(false) {} |
+ |
+ bool delegates_to_traceimpl() const { return delegates_to_traceimpl_; } |
bool VisitMemberExpr(MemberExpr* member) { |
// In weak callbacks, consider any occurrence as a correct usage. |
@@ -383,6 +385,11 @@ class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> { |
if (CXXMemberCallExpr* expr = dyn_cast<CXXMemberCallExpr>(call)) { |
if (CheckTraceFieldCall(expr) || CheckRegisterWeakMembers(expr)) |
return true; |
+ |
+ if (expr->getMethodDecl()->getNameAsString() == kTraceImplName) { |
+ delegates_to_traceimpl_ = true; |
+ return true; |
+ } |
} |
CheckTraceBaseCall(call); |
@@ -415,6 +422,23 @@ class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> { |
void CheckCXXDependentScopeMemberExpr(CallExpr* call, |
CXXDependentScopeMemberExpr* expr) { |
string fn_name = expr->getMember().getAsString(); |
+ |
+ // Check for VisitorDispatcher::trace(field) |
+ if (!expr->isImplicitAccess()) { |
+ if (clang::DeclRefExpr* base_decl = |
+ clang::dyn_cast<clang::DeclRefExpr>(expr->getBase())) { |
+ if (Config::IsVisitorDispatcherType(base_decl->getType()) && |
+ call->getNumArgs() == 1 && fn_name == kTraceName) { |
+ FindFieldVisitor finder; |
+ finder.TraverseStmt(call->getArg(0)); |
+ if (finder.field()) |
+ FoundField(finder.field()); |
+ |
+ return; |
+ } |
+ } |
+ } |
+ |
CXXRecordDecl* tmpl = GetDependentTemplatedDecl(expr); |
if (!tmpl) |
return; |
@@ -565,6 +589,7 @@ class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> { |
CXXMethodDecl* trace_; |
RecordInfo* info_; |
+ bool delegates_to_traceimpl_; |
}; |
// This visitor checks that the fields of a class and the fields of |
@@ -1303,6 +1328,11 @@ class BlinkGCPluginConsumer : public ASTConsumer { |
CheckTraceVisitor visitor(trace, parent); |
visitor.TraverseCXXMethodDecl(trace); |
+ // Skip reporting if this trace method is a just delegate to |
+ // traceImpl method. We will report on CheckTraceMethod on traceImpl method. |
+ if (visitor.delegates_to_traceimpl()) |
+ return; |
+ |
for (RecordInfo::Bases::iterator it = parent->GetBases().begin(); |
it != parent->GetBases().end(); |
++it) { |