//===- GlobalDecl.h - Global declaration holder -----------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor
// together with its type.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_GLOBALDECL_H
#define LLVM_CLANG_AST_GLOBALDECL_H

#include "clang/AST/Attr.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/Basic/ABI.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/type_traits.h"
#include <cassert>

namespace clang {

enum class DynamicInitKind : unsigned {
  NoStub = 0,
  Initializer,
  AtExit,
  GlobalArrayDestructor
};

enum class KernelReferenceKind : unsigned {
  Kernel = 0,
  Stub = 1,
};

/// GlobalDecl - represents a global declaration. This can either be a
/// CXXConstructorDecl and the constructor type (Base, Complete).
/// a CXXDestructorDecl and the destructor type (Base, Complete),
/// a FunctionDecl and the kernel reference type (Kernel, Stub), or
/// a VarDecl, a FunctionDecl or a BlockDecl.
///
/// When a new type of GlobalDecl is added, the following places should
/// be updated to convert a Decl* to a GlobalDecl:
/// PredefinedExpr::ComputeName() in lib/AST/Expr.cpp.
/// getParentOfLocalEntity() in lib/AST/ItaniumMangle.cpp
/// ASTNameGenerator::Implementation::writeFuncOrVarName in lib/AST/Mangle.cpp
///
class GlobalDecl {
  llvm::PointerIntPair<const Decl *, 3> Value;
  unsigned MultiVersionIndex = 0;

  void Init(const Decl *D) {
    assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
    assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
    assert(!D->hasAttr<CUDAGlobalAttr>() && "Use other ctor with GPU kernels!");

    Value.setPointer(D);
  }

public:
  GlobalDecl() = default;
  GlobalDecl(const VarDecl *D) { Init(D);}
  GlobalDecl(const FunctionDecl *D, unsigned MVIndex = 0)
      : MultiVersionIndex(MVIndex) {
    if (!D->hasAttr<CUDAGlobalAttr>()) {
      Init(D);
      return;
    }
    Value.setPointerAndInt(D, unsigned(getDefaultKernelReference(D)));
  }
  GlobalDecl(const FunctionDecl *D, KernelReferenceKind Kind)
      : Value(D, unsigned(Kind)) {
    assert(D->hasAttr<CUDAGlobalAttr>() && "Decl is not a GPU kernel!");
  }
  GlobalDecl(const NamedDecl *D) { Init(D); }
  GlobalDecl(const BlockDecl *D) { Init(D); }
  GlobalDecl(const CapturedDecl *D) { Init(D); }
  GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
  GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
  GlobalDecl(const OMPDeclareMapperDecl *D) { Init(D); }
  GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {}
  GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {}
  GlobalDecl(const VarDecl *D, DynamicInitKind StubKind)
      : Value(D, unsigned(StubKind)) {}

  GlobalDecl getCanonicalDecl() const {
    GlobalDecl CanonGD;
    CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
    CanonGD.Value.setInt(Value.getInt());
    CanonGD.MultiVersionIndex = MultiVersionIndex;

    return CanonGD;
  }

  const Decl *getDecl() const { return Value.getPointer(); }

  CXXCtorType getCtorType() const {
    assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
    return static_cast<CXXCtorType>(Value.getInt());
  }

  CXXDtorType getDtorType() const {
    assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
    return static_cast<CXXDtorType>(Value.getInt());
  }

  DynamicInitKind getDynamicInitKind() const {
    assert(isa<VarDecl>(getDecl()) &&
           cast<VarDecl>(getDecl())->hasGlobalStorage() &&
           "Decl is not a global variable!");
    return static_cast<DynamicInitKind>(Value.getInt());
  }

  unsigned getMultiVersionIndex() const {
    assert(isa<FunctionDecl>(
               getDecl()) &&
               !cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
           !isa<CXXConstructorDecl>(getDecl()) &&
           !isa<CXXDestructorDecl>(getDecl()) &&
           "Decl is not a plain FunctionDecl!");
    return MultiVersionIndex;
  }

  KernelReferenceKind getKernelReferenceKind() const {
    assert(((isa<FunctionDecl>(getDecl()) &&
             cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>()) ||
            (isa<FunctionTemplateDecl>(getDecl()) &&
             cast<FunctionTemplateDecl>(getDecl())
                 ->getTemplatedDecl()
                 ->hasAttr<CUDAGlobalAttr>())) &&
           "Decl is not a GPU kernel!");
    return static_cast<KernelReferenceKind>(Value.getInt());
  }

  friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
    return LHS.Value == RHS.Value &&
           LHS.MultiVersionIndex == RHS.MultiVersionIndex;
  }

  void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }

  explicit operator bool() const { return getAsOpaquePtr(); }

  static GlobalDecl getFromOpaquePtr(void *P) {
    GlobalDecl GD;
    GD.Value.setFromOpaqueValue(P);
    return GD;
  }

  static KernelReferenceKind getDefaultKernelReference(const FunctionDecl *D) {
    return D->getLangOpts().CUDAIsDevice ? KernelReferenceKind::Kernel
                                         : KernelReferenceKind::Stub;
  }

  GlobalDecl getWithDecl(const Decl *D) {
    GlobalDecl Result(*this);
    Result.Value.setPointer(D);
    return Result;
  }

  GlobalDecl getWithCtorType(CXXCtorType Type) {
    assert(isa<CXXConstructorDecl>(getDecl()));
    GlobalDecl Result(*this);
    Result.Value.setInt(Type);
    return Result;
  }

  GlobalDecl getWithDtorType(CXXDtorType Type) {
    assert(isa<CXXDestructorDecl>(getDecl()));
    GlobalDecl Result(*this);
    Result.Value.setInt(Type);
    return Result;
  }

  GlobalDecl getWithMultiVersionIndex(unsigned Index) {
    assert(isa<FunctionDecl>(getDecl()) &&
           !cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
           !isa<CXXConstructorDecl>(getDecl()) &&
           !isa<CXXDestructorDecl>(getDecl()) &&
           "Decl is not a plain FunctionDecl!");
    GlobalDecl Result(*this);
    Result.MultiVersionIndex = Index;
    return Result;
  }

  GlobalDecl getWithKernelReferenceKind(KernelReferenceKind Kind) {
    assert(isa<FunctionDecl>(getDecl()) &&
           cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
           "Decl is not a GPU kernel!");
    GlobalDecl Result(*this);
    Result.Value.setInt(unsigned(Kind));
    return Result;
  }
};

} // namespace clang

namespace llvm {

  template<> struct DenseMapInfo<clang::GlobalDecl> {
    static inline clang::GlobalDecl getEmptyKey() {
      return clang::GlobalDecl();
    }

    static inline clang::GlobalDecl getTombstoneKey() {
      return clang::GlobalDecl::
        getFromOpaquePtr(reinterpret_cast<void*>(-1));
    }

    static unsigned getHashValue(clang::GlobalDecl GD) {
      return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
    }

    static bool isEqual(clang::GlobalDecl LHS,
                        clang::GlobalDecl RHS) {
      return LHS == RHS;
    }
  };

} // namespace llvm

#endif // LLVM_CLANG_AST_GLOBALDECL_H
