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

// This file defines the names used by GC infrastructure.

// TODO: Restructure the name determination to use fully qualified names (ala,
// blink::Foo) so that the plugin can be enabled for all of chromium. Doing so
// would allow us to catch errors with structures outside of blink that might
// have unsafe pointers to GC allocated blink structures.

#ifndef TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
#define TOOLS_BLINK_GC_PLUGIN_CONFIG_H_

#include <cassert>

#include "RecordInfo.h"
#include "clang/AST/AST.h"
#include "clang/AST/Attr.h"

extern const char kNewOperatorName[];
extern const char kCreateName[];
extern const char kTraceName[];
extern const char kFinalizeName[];
extern const char kTraceAfterDispatchName[];
extern const char kRegisterWeakMembersName[];
extern const char kHeapAllocatorName[];
extern const char kTraceIfNeededName[];
extern const char kVisitorDispatcherName[];
extern const char kVisitorVarName[];
extern const char kAdjustAndMarkName[];
extern const char kIsHeapObjectAliveName[];
extern const char kConstIteratorName[];
extern const char kIteratorName[];
extern const char kConstReverseIteratorName[];
extern const char kReverseIteratorName[];

class Config {
 private:
  // Checks that the namespace matches the expected namespace and that the type
  // takes at least |expected_minimum_arg_count| template arguments. If both
  // requirements are fulfilled, populates |args| with the first
  // |expected_minimum_arg_count| template arguments. Verifying only the minimum
  // expected argument keeps the plugin resistant to changes in the type
  // definitions (to some extent)
  static bool VerifyNamespaceAndArgCount(std::string expected_ns_name,
                                         int expected_minimum_arg_count,
                                         llvm::StringRef ns_name,
                                         RecordInfo* info,
                                         RecordInfo::TemplateArgs* args) {
    return (ns_name == expected_ns_name) &&
           info->GetTemplateArgs(expected_minimum_arg_count, args);
  }

 public:
  static bool IsMember(llvm::StringRef name,
                       llvm::StringRef ns_name,
                       RecordInfo* info,
                       RecordInfo::TemplateArgs* args) {
    if (name == "BasicMember") {
      if (!VerifyNamespaceAndArgCount("cppgc", 2, ns_name, info, args))
        return false;
      return (*args)[1]->getAsRecordDecl()->getName() == "StrongMemberTag";
    }
    return false;
  }

  static bool IsWeakMember(llvm::StringRef name,
                           llvm::StringRef ns_name,
                           RecordInfo* info,
                           RecordInfo::TemplateArgs* args) {
    if (name == "BasicMember") {
      if (!VerifyNamespaceAndArgCount("cppgc", 2, ns_name, info, args))
        return false;
      return (*args)[1]->getAsRecordDecl()->getName() == "WeakMemberTag";
    }
    return false;
  }

  static bool IsPersistent(llvm::StringRef name,
                           llvm::StringRef ns_name,
                           RecordInfo* info,
                           RecordInfo::TemplateArgs* args) {
    if (name == "BasicPersistent") {
      return VerifyNamespaceAndArgCount("cppgc", 1, ns_name, info, args);
    }
    return false;
  }

  static bool IsCrossThreadPersistent(llvm::StringRef name,
                                      llvm::StringRef ns_name,
                                      RecordInfo* info,
                                      RecordInfo::TemplateArgs* args) {
    if (name == "BasicCrossThreadPersistent") {
      return VerifyNamespaceAndArgCount("cppgc", 1, ns_name, info, args);
    }
    return false;
  }

  static bool IsRefPtr(llvm::StringRef name) { return name == "scoped_refptr"; }

  static bool IsWeakPtr(llvm::StringRef name) { return name == "WeakPtr"; }

  static bool IsRefOrWeakPtr(llvm::StringRef name) {
    return IsRefPtr(name) || IsWeakPtr(name);
  }

  static bool IsUniquePtr(llvm::StringRef name) {
    return name == "unique_ptr";
  }

  static bool IsTraceWrapperV8Reference(llvm::StringRef name,
                                        llvm::StringRef ns_name,
                                        RecordInfo* info,
                                        RecordInfo::TemplateArgs* args) {
    return name == "TraceWrapperV8Reference" &&
           VerifyNamespaceAndArgCount("blink", 1, ns_name, info, args);
  }

  static bool IsWTFCollection(llvm::StringRef name) {
    return name == "Vector" ||
           name == "Deque" ||
           name == "HashSet" ||
           name == "LinkedHashSet" ||
           name == "HashCountedSet" ||
           name == "HashMap";
  }

  static bool IsSTDCollection(llvm::StringRef name) {
    return name == "vector" || name == "map" || name == "unordered_map" ||
           name == "set" || name == "unordered_set" || name == "array" ||
           name == "optional" || name == "variant";
  }

  static bool IsGCCollection(llvm::StringRef name) {
    return name == "HeapVector" || name == "HeapDeque" ||
           name == "HeapHashSet" || name == "HeapLinkedHashSet" ||
           name == "HeapHashCountedSet" || name == "HeapHashMap";
  }

  static bool IsHashMap(llvm::StringRef name) {
    return name == "HashMap" || name == "HeapHashMap" || name == "map" ||
           name == "unordered_map";
  }

  // Assumes name is a valid collection name.
  static size_t CollectionDimension(llvm::StringRef name) {
    // In case we're dealing with a variant, we want to collect the whole
    // parameter pack.
    if (name == "variant") {
      return 0;
    }
    return (IsHashMap(name) || name == "pair") ? 2 : 1;
  }

  static bool IsRefCountedBase(llvm::StringRef name) {
    return name == "RefCounted" ||
           name == "ThreadSafeRefCounted";
  }

  static bool IsGCSimpleBase(llvm::StringRef name) {
    return name == "GarbageCollected";
  }

  static bool IsGCMixinBase(llvm::StringRef name) {
    return name == "GarbageCollectedMixin";
  }

  static bool IsGCBase(llvm::StringRef name) {
    return IsGCSimpleBase(name) || IsGCMixinBase(name);
  }

  static bool IsIterator(llvm::StringRef name) {
    return name == kIteratorName || name == kConstIteratorName ||
           name == kReverseIteratorName || name == kConstReverseIteratorName;
  }

  // Returns true of the base classes that do not need a vtable entry for trace
  // because they cannot possibly initiate a GC during construction.
  static bool IsSafePolymorphicBase(llvm::StringRef name) {
    return IsGCBase(name) || IsRefCountedBase(name);
  }

  static bool IsAnnotated(const clang::Decl* decl, const std::string& anno) {
    clang::AnnotateAttr* attr = decl->getAttr<clang::AnnotateAttr>();
    return attr && (attr->getAnnotation() == anno);
  }

  static bool IsIgnoreAnnotated(const clang::Decl* decl) {
    return IsAnnotated(decl, "blink_gc_plugin_ignore");
  }

  static bool IsVisitor(llvm::StringRef name) { return name == "Visitor"; }

  static bool IsVisitorPtrType(const clang::QualType& formal_type) {
    if (!formal_type->isPointerType())
      return false;

    clang::CXXRecordDecl* pointee_type =
        formal_type->getPointeeType()->getAsCXXRecordDecl();
    if (!pointee_type)
      return false;

    if (!IsVisitor(pointee_type->getName()))
      return false;

    return true;
  }

  static bool IsVisitorDispatcherType(const clang::QualType& formal_type) {
    if (const clang::SubstTemplateTypeParmType* subst_type =
            clang::dyn_cast<clang::SubstTemplateTypeParmType>(
                formal_type.getTypePtr())) {
      if (IsVisitorPtrType(subst_type->getReplacementType())) {
        // VisitorDispatcher template parameter substituted to Visitor*.
        return true;
      }
    } else if (const clang::TemplateTypeParmType* parm_type =
                   clang::dyn_cast<clang::TemplateTypeParmType>(
                       formal_type.getTypePtr())) {
      if (parm_type->getDecl()->getName() == kVisitorDispatcherName) {
        // Unresolved, but its parameter name is VisitorDispatcher.
        return true;
      }
    }

    return IsVisitorPtrType(formal_type);
  }

  enum TraceMethodType {
    NOT_TRACE_METHOD,
    TRACE_METHOD,
    TRACE_AFTER_DISPATCH_METHOD,
  };

  static TraceMethodType GetTraceMethodType(const clang::FunctionDecl* method) {
    if (method->getNumParams() != 1)
      return NOT_TRACE_METHOD;

    const std::string& name = method->getNameAsString();
    if (name != kTraceName && name != kTraceAfterDispatchName)
      return NOT_TRACE_METHOD;

    const clang::QualType& formal_type = method->getParamDecl(0)->getType();
    if (!IsVisitorPtrType(formal_type)) {
      return NOT_TRACE_METHOD;
    }

    if (name == kTraceName)
      return TRACE_METHOD;
    if (name == kTraceAfterDispatchName)
      return TRACE_AFTER_DISPATCH_METHOD;

    assert(false && "Should not reach here");
    return NOT_TRACE_METHOD;
  }

  static bool IsTraceMethod(const clang::FunctionDecl* method) {
    return GetTraceMethodType(method) != NOT_TRACE_METHOD;
  }

  static bool IsTraceWrappersMethod(const clang::FunctionDecl* method);

  static bool StartsWith(const std::string& str, const std::string& prefix) {
    if (prefix.size() > str.size())
      return false;
    return str.compare(0, prefix.size(), prefix) == 0;
  }

  static bool EndsWith(const std::string& str, const std::string& suffix) {
    if (suffix.size() > str.size())
      return false;
    return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
  }

  // Test if a template specialization is an instantiation.
  static bool IsTemplateInstantiation(clang::CXXRecordDecl* record);
};

#endif  // TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
