bool BlinkGCPluginConsumer::HasNonEmptyFinalizer(RecordInfo* info) {
  CXXDestructorDecl* dtor = info->record()->getDestructor();
  if (dtor && dtor->isUserProvided()) {
    if (!dtor->hasBody() || !EmptyStmtVisitor::isEmpty(dtor->getBody()))
      return true;
  }
  for (RecordInfo::Bases::iterator it = info->GetBases().begin();
       it != info->GetBases().end();
       ++it) {
    if (HasNonEmptyFinalizer(it->second.info()))
      return true;
  }
  for (RecordInfo::Fields::iterator it = info->GetFields().begin();
       it != info->GetFields().end();
       ++it) {
    if (it->second.edge()->NeedsFinalization())
      return true;
  }
  return false;
}
// TODO: Should we collect destructors similar to trace methods?
void BlinkGCPluginConsumer::CheckFinalization(RecordInfo* info) {
  CXXDestructorDecl* dtor = info->record()->getDestructor();

  // For finalized classes, check the finalization method if possible.
  if (info->IsGCFinalized()) {
    if (dtor && dtor->hasBody()) {
      CheckFinalizerVisitor visitor(&cache_, info->IsEagerlyFinalized());
      visitor.TraverseCXXMethodDecl(dtor);
      if (!visitor.finalized_fields().empty()) {
        ReportFinalizerAccessesFinalizedFields(
            dtor, &visitor.finalized_fields());
      }
    }
    return;
  }

  // Don't require finalization of a mixin that has not yet been "mixed in".
  if (info->IsGCMixin())
    return;

  // Report the finalization error, and proceed to print possible causes for
  // the finalization requirement.
  ReportClassRequiresFinalization(info);

  if (dtor && dtor->isUserProvided())
    NoteUserDeclaredDestructor(dtor);

  for (RecordInfo::Bases::iterator it = info->GetBases().begin();
       it != info->GetBases().end();
       ++it) {
    if (it->second.info()->NeedsFinalization())
      NoteBaseRequiresFinalization(&it->second);
  }

  for (RecordInfo::Fields::iterator it = info->GetFields().begin();
       it != info->GetFields().end();
       ++it) {
    if (it->second.edge()->NeedsFinalization())
      NoteField(&it->second, diag_field_requires_finalization_note_);
  }
}