GlobalDecl.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- GlobalDecl.h - Global declaration holder -----------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor
  15. // together with its type.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_CLANG_AST_GLOBALDECL_H
  19. #define LLVM_CLANG_AST_GLOBALDECL_H
  20. #include "clang/AST/Attr.h"
  21. #include "clang/AST/DeclCXX.h"
  22. #include "clang/AST/DeclObjC.h"
  23. #include "clang/AST/DeclOpenMP.h"
  24. #include "clang/AST/DeclTemplate.h"
  25. #include "clang/Basic/ABI.h"
  26. #include "clang/Basic/LLVM.h"
  27. #include "llvm/ADT/DenseMapInfo.h"
  28. #include "llvm/ADT/PointerIntPair.h"
  29. #include "llvm/Support/Casting.h"
  30. #include "llvm/Support/type_traits.h"
  31. #include <cassert>
  32. namespace clang {
  33. enum class DynamicInitKind : unsigned {
  34. NoStub = 0,
  35. Initializer,
  36. AtExit,
  37. GlobalArrayDestructor
  38. };
  39. enum class KernelReferenceKind : unsigned {
  40. Kernel = 0,
  41. Stub = 1,
  42. };
  43. /// GlobalDecl - represents a global declaration. This can either be a
  44. /// CXXConstructorDecl and the constructor type (Base, Complete).
  45. /// a CXXDestructorDecl and the destructor type (Base, Complete),
  46. /// a FunctionDecl and the kernel reference type (Kernel, Stub), or
  47. /// a VarDecl, a FunctionDecl or a BlockDecl.
  48. ///
  49. /// When a new type of GlobalDecl is added, the following places should
  50. /// be updated to convert a Decl* to a GlobalDecl:
  51. /// PredefinedExpr::ComputeName() in lib/AST/Expr.cpp.
  52. /// getParentOfLocalEntity() in lib/AST/ItaniumMangle.cpp
  53. /// ASTNameGenerator::Implementation::writeFuncOrVarName in lib/AST/Mangle.cpp
  54. ///
  55. class GlobalDecl {
  56. llvm::PointerIntPair<const Decl *, 3> Value;
  57. unsigned MultiVersionIndex = 0;
  58. void Init(const Decl *D) {
  59. assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
  60. assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
  61. assert(!D->hasAttr<CUDAGlobalAttr>() && "Use other ctor with GPU kernels!");
  62. Value.setPointer(D);
  63. }
  64. public:
  65. GlobalDecl() = default;
  66. GlobalDecl(const VarDecl *D) { Init(D);}
  67. GlobalDecl(const FunctionDecl *D, unsigned MVIndex = 0)
  68. : MultiVersionIndex(MVIndex) {
  69. if (!D->hasAttr<CUDAGlobalAttr>()) {
  70. Init(D);
  71. return;
  72. }
  73. Value.setPointerAndInt(D, unsigned(getDefaultKernelReference(D)));
  74. }
  75. GlobalDecl(const FunctionDecl *D, KernelReferenceKind Kind)
  76. : Value(D, unsigned(Kind)) {
  77. assert(D->hasAttr<CUDAGlobalAttr>() && "Decl is not a GPU kernel!");
  78. }
  79. GlobalDecl(const NamedDecl *D) { Init(D); }
  80. GlobalDecl(const BlockDecl *D) { Init(D); }
  81. GlobalDecl(const CapturedDecl *D) { Init(D); }
  82. GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
  83. GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
  84. GlobalDecl(const OMPDeclareMapperDecl *D) { Init(D); }
  85. GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {}
  86. GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {}
  87. GlobalDecl(const VarDecl *D, DynamicInitKind StubKind)
  88. : Value(D, unsigned(StubKind)) {}
  89. GlobalDecl getCanonicalDecl() const {
  90. GlobalDecl CanonGD;
  91. CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
  92. CanonGD.Value.setInt(Value.getInt());
  93. CanonGD.MultiVersionIndex = MultiVersionIndex;
  94. return CanonGD;
  95. }
  96. const Decl *getDecl() const { return Value.getPointer(); }
  97. CXXCtorType getCtorType() const {
  98. assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
  99. return static_cast<CXXCtorType>(Value.getInt());
  100. }
  101. CXXDtorType getDtorType() const {
  102. assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
  103. return static_cast<CXXDtorType>(Value.getInt());
  104. }
  105. DynamicInitKind getDynamicInitKind() const {
  106. assert(isa<VarDecl>(getDecl()) &&
  107. cast<VarDecl>(getDecl())->hasGlobalStorage() &&
  108. "Decl is not a global variable!");
  109. return static_cast<DynamicInitKind>(Value.getInt());
  110. }
  111. unsigned getMultiVersionIndex() const {
  112. assert(isa<FunctionDecl>(
  113. getDecl()) &&
  114. !cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
  115. !isa<CXXConstructorDecl>(getDecl()) &&
  116. !isa<CXXDestructorDecl>(getDecl()) &&
  117. "Decl is not a plain FunctionDecl!");
  118. return MultiVersionIndex;
  119. }
  120. KernelReferenceKind getKernelReferenceKind() const {
  121. assert(((isa<FunctionDecl>(getDecl()) &&
  122. cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>()) ||
  123. (isa<FunctionTemplateDecl>(getDecl()) &&
  124. cast<FunctionTemplateDecl>(getDecl())
  125. ->getTemplatedDecl()
  126. ->hasAttr<CUDAGlobalAttr>())) &&
  127. "Decl is not a GPU kernel!");
  128. return static_cast<KernelReferenceKind>(Value.getInt());
  129. }
  130. friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
  131. return LHS.Value == RHS.Value &&
  132. LHS.MultiVersionIndex == RHS.MultiVersionIndex;
  133. }
  134. void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
  135. explicit operator bool() const { return getAsOpaquePtr(); }
  136. static GlobalDecl getFromOpaquePtr(void *P) {
  137. GlobalDecl GD;
  138. GD.Value.setFromOpaqueValue(P);
  139. return GD;
  140. }
  141. static KernelReferenceKind getDefaultKernelReference(const FunctionDecl *D) {
  142. return D->getLangOpts().CUDAIsDevice ? KernelReferenceKind::Kernel
  143. : KernelReferenceKind::Stub;
  144. }
  145. GlobalDecl getWithDecl(const Decl *D) {
  146. GlobalDecl Result(*this);
  147. Result.Value.setPointer(D);
  148. return Result;
  149. }
  150. GlobalDecl getWithCtorType(CXXCtorType Type) {
  151. assert(isa<CXXConstructorDecl>(getDecl()));
  152. GlobalDecl Result(*this);
  153. Result.Value.setInt(Type);
  154. return Result;
  155. }
  156. GlobalDecl getWithDtorType(CXXDtorType Type) {
  157. assert(isa<CXXDestructorDecl>(getDecl()));
  158. GlobalDecl Result(*this);
  159. Result.Value.setInt(Type);
  160. return Result;
  161. }
  162. GlobalDecl getWithMultiVersionIndex(unsigned Index) {
  163. assert(isa<FunctionDecl>(getDecl()) &&
  164. !cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
  165. !isa<CXXConstructorDecl>(getDecl()) &&
  166. !isa<CXXDestructorDecl>(getDecl()) &&
  167. "Decl is not a plain FunctionDecl!");
  168. GlobalDecl Result(*this);
  169. Result.MultiVersionIndex = Index;
  170. return Result;
  171. }
  172. GlobalDecl getWithKernelReferenceKind(KernelReferenceKind Kind) {
  173. assert(isa<FunctionDecl>(getDecl()) &&
  174. cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
  175. "Decl is not a GPU kernel!");
  176. GlobalDecl Result(*this);
  177. Result.Value.setInt(unsigned(Kind));
  178. return Result;
  179. }
  180. };
  181. } // namespace clang
  182. namespace llvm {
  183. template<> struct DenseMapInfo<clang::GlobalDecl> {
  184. static inline clang::GlobalDecl getEmptyKey() {
  185. return clang::GlobalDecl();
  186. }
  187. static inline clang::GlobalDecl getTombstoneKey() {
  188. return clang::GlobalDecl::
  189. getFromOpaquePtr(reinterpret_cast<void*>(-1));
  190. }
  191. static unsigned getHashValue(clang::GlobalDecl GD) {
  192. return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
  193. }
  194. static bool isEqual(clang::GlobalDecl LHS,
  195. clang::GlobalDecl RHS) {
  196. return LHS == RHS;
  197. }
  198. };
  199. } // namespace llvm
  200. #endif // LLVM_CLANG_AST_GLOBALDECL_H
  201. #ifdef __GNUC__
  202. #pragma GCC diagnostic pop
  203. #endif