// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "CheckFieldsVisitor.h"

#include <cassert>

#include "RecordInfo.h"
#include "llvm/Support/ErrorHandling.h"

CheckFieldsVisitor::CheckFieldsVisitor(const BlinkGCPluginOptions& options)
    : options_(options), current_(0), stack_allocated_host_(false) {}

CheckFieldsVisitor::Errors& CheckFieldsVisitor::invalid_fields() {
  return invalid_fields_;
}

bool CheckFieldsVisitor::ContainsInvalidFields(RecordInfo* info) {
  stack_allocated_host_ = info->IsStackAllocated();
  managed_host_ = stack_allocated_host_ ||
                  info->IsGCAllocated() ||
                  info->IsNonNewable() ||
                  info->IsOnlyPlacementNewable();
  for (RecordInfo::Fields::iterator it = info->GetFields().begin();
       it != info->GetFields().end();
       ++it) {
    context().clear();
    current_ = &it->second;
    current_->edge()->Accept(this);
  }
  return !invalid_fields_.empty();
}

void CheckFieldsVisitor::AtMember(Member*) {
  if (managed_host_)
    return;
  // A member is allowed to appear in the context of a root.
  for (Context::iterator it = context().begin();
       it != context().end();
       ++it) {
    if ((*it)->Kind() == Edge::kRoot)
      return;
  }
  invalid_fields_.push_back(std::make_pair(current_, kMemberInUnmanaged));
}

void CheckFieldsVisitor::AtWeakMember(WeakMember*) {
  // TODO(sof): remove this once crbug.com/724418's change
  // has safely been rolled out.
  if (options_.enable_weak_members_in_unmanaged_classes)
    return;
  AtMember(nullptr);
}

void CheckFieldsVisitor::AtIterator(Iterator* edge) {
  if (!managed_host_)
    return;

  if (!stack_allocated_host_ && edge->on_heap())
    invalid_fields_.push_back(std::make_pair(current_, kIteratorToGCManaged));
}

void CheckFieldsVisitor::AtValue(Value* edge) {
  // TODO: what should we do to check unions?
  if (edge->value()->record()->isUnion())
    return;

  if (!stack_allocated_host_ && edge->value()->IsStackAllocated()) {
    invalid_fields_.push_back(std::make_pair(current_, kPtrFromHeapToStack));
    return;
  }

  if (!Parent() &&
      edge->value()->IsGCDerived() &&
      !edge->value()->IsGCMixin()) {
    invalid_fields_.push_back(std::make_pair(current_, kGCDerivedPartObject));
    return;
  }

  // Members/WeakMembers are prohibited if the host is stack allocated, but
  // heap collections with Members are okay.
  if (stack_allocated_host_ && Parent() &&
      (Parent()->IsMember() || Parent()->IsWeakMember())) {
    if (!GrandParent() || !GrandParent()->IsCollection()) {
      invalid_fields_.push_back(
          std::make_pair(current_, kMemberInStackAllocated));
      return;
    }
  }

  // If in a stack allocated context, be fairly insistent that T in Member<T>
  // is GC allocated, as stack allocated objects do not have a trace()
  // that separately verifies the validity of Member<T>.
  //
  // Notice that an error is only reported if T's definition is in scope;
  // we do not require that it must be brought into scope as that would
  // prevent declarations of mutually dependent class types.
  //
  // (Note: Member<>'s constructor will at run-time verify that the
  // pointer it wraps is indeed heap allocated.)
  if (stack_allocated_host_ && Parent() &&
      (Parent()->IsMember() || Parent()->IsWeakMember()) &&
      edge->value()->HasDefinition() && !edge->value()->IsGCAllocated()) {
    invalid_fields_.push_back(std::make_pair(current_, kMemberToGCUnmanaged));
    return;
  }

  if (!Parent() || !edge->value()->IsGCAllocated())
    return;

  // Disallow unique_ptr<T>, scoped_refptr<T>, WeakPtr<T>.
  if (Parent()->IsUniquePtr() || Parent()->IsRefPtr()) {
    invalid_fields_.push_back(std::make_pair(
        current_, InvalidSmartPtr(Parent())));
    return;
  }
  if (Parent()->IsRawPtr() && !stack_allocated_host_) {
    RawPtr* rawPtr = static_cast<RawPtr*>(Parent());
    Error error = rawPtr->HasReferenceType() ?
        kReferencePtrToGCManaged : kRawPtrToGCManaged;
    invalid_fields_.push_back(std::make_pair(current_, error));
  }
}

void CheckFieldsVisitor::AtCollection(Collection* edge) {
  if (edge->on_heap() && Parent() && Parent()->IsUniquePtr())
    invalid_fields_.push_back(std::make_pair(current_, kUniquePtrToGCManaged));
}

CheckFieldsVisitor::Error CheckFieldsVisitor::InvalidSmartPtr(Edge* ptr) {
  if (ptr->IsRefPtr())
    return ptr->Kind() == Edge::kStrong ? kRefPtrToGCManaged
                                        : kWeakPtrToGCManaged;
  if (ptr->IsUniquePtr())
    return kUniquePtrToGCManaged;
  llvm_unreachable("Unknown smart pointer kind");
}
