File indexing completed on 2026-05-10 08:36:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_AST_GLOBALDECL_H
0015 #define LLVM_CLANG_AST_GLOBALDECL_H
0016
0017 #include "clang/AST/Attr.h"
0018 #include "clang/AST/DeclCXX.h"
0019 #include "clang/AST/DeclObjC.h"
0020 #include "clang/AST/DeclOpenMP.h"
0021 #include "clang/AST/DeclTemplate.h"
0022 #include "clang/Basic/ABI.h"
0023 #include "clang/Basic/LLVM.h"
0024 #include "llvm/ADT/DenseMapInfo.h"
0025 #include "llvm/ADT/PointerIntPair.h"
0026 #include "llvm/Support/Casting.h"
0027 #include "llvm/Support/type_traits.h"
0028 #include <cassert>
0029
0030 namespace clang {
0031
0032 enum class DynamicInitKind : unsigned {
0033 NoStub = 0,
0034 Initializer,
0035 AtExit,
0036 GlobalArrayDestructor
0037 };
0038
0039 enum class KernelReferenceKind : unsigned {
0040 Kernel = 0,
0041 Stub = 1,
0042 };
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 class GlobalDecl {
0057 llvm::PointerIntPair<const Decl *, 3> Value;
0058 unsigned MultiVersionIndex = 0;
0059
0060 void Init(const Decl *D) {
0061 assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
0062 assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
0063 assert(!D->hasAttr<CUDAGlobalAttr>() && "Use other ctor with GPU kernels!");
0064
0065 Value.setPointer(D);
0066 }
0067
0068 public:
0069 GlobalDecl() = default;
0070 GlobalDecl(const VarDecl *D) { Init(D);}
0071 GlobalDecl(const FunctionDecl *D, unsigned MVIndex = 0)
0072 : MultiVersionIndex(MVIndex) {
0073 if (!D->hasAttr<CUDAGlobalAttr>()) {
0074 Init(D);
0075 return;
0076 }
0077 Value.setPointerAndInt(D, unsigned(getDefaultKernelReference(D)));
0078 }
0079 GlobalDecl(const FunctionDecl *D, KernelReferenceKind Kind)
0080 : Value(D, unsigned(Kind)) {
0081 assert(D->hasAttr<CUDAGlobalAttr>() && "Decl is not a GPU kernel!");
0082 }
0083 GlobalDecl(const NamedDecl *D) { Init(D); }
0084 GlobalDecl(const BlockDecl *D) { Init(D); }
0085 GlobalDecl(const CapturedDecl *D) { Init(D); }
0086 GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
0087 GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
0088 GlobalDecl(const OMPDeclareMapperDecl *D) { Init(D); }
0089 GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {}
0090 GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {}
0091 GlobalDecl(const VarDecl *D, DynamicInitKind StubKind)
0092 : Value(D, unsigned(StubKind)) {}
0093
0094 GlobalDecl getCanonicalDecl() const {
0095 GlobalDecl CanonGD;
0096 CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
0097 CanonGD.Value.setInt(Value.getInt());
0098 CanonGD.MultiVersionIndex = MultiVersionIndex;
0099
0100 return CanonGD;
0101 }
0102
0103 const Decl *getDecl() const { return Value.getPointer(); }
0104
0105 CXXCtorType getCtorType() const {
0106 assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
0107 return static_cast<CXXCtorType>(Value.getInt());
0108 }
0109
0110 CXXDtorType getDtorType() const {
0111 assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
0112 return static_cast<CXXDtorType>(Value.getInt());
0113 }
0114
0115 DynamicInitKind getDynamicInitKind() const {
0116 assert(isa<VarDecl>(getDecl()) &&
0117 cast<VarDecl>(getDecl())->hasGlobalStorage() &&
0118 "Decl is not a global variable!");
0119 return static_cast<DynamicInitKind>(Value.getInt());
0120 }
0121
0122 unsigned getMultiVersionIndex() const {
0123 assert(isa<FunctionDecl>(
0124 getDecl()) &&
0125 !cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
0126 !isa<CXXConstructorDecl>(getDecl()) &&
0127 !isa<CXXDestructorDecl>(getDecl()) &&
0128 "Decl is not a plain FunctionDecl!");
0129 return MultiVersionIndex;
0130 }
0131
0132 KernelReferenceKind getKernelReferenceKind() const {
0133 assert(((isa<FunctionDecl>(getDecl()) &&
0134 cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>()) ||
0135 (isa<FunctionTemplateDecl>(getDecl()) &&
0136 cast<FunctionTemplateDecl>(getDecl())
0137 ->getTemplatedDecl()
0138 ->hasAttr<CUDAGlobalAttr>())) &&
0139 "Decl is not a GPU kernel!");
0140 return static_cast<KernelReferenceKind>(Value.getInt());
0141 }
0142
0143 friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
0144 return LHS.Value == RHS.Value &&
0145 LHS.MultiVersionIndex == RHS.MultiVersionIndex;
0146 }
0147
0148 bool operator!=(const GlobalDecl &Other) const {
0149 return !(*this == Other);
0150 }
0151
0152 void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
0153
0154 explicit operator bool() const { return getAsOpaquePtr(); }
0155
0156 static GlobalDecl getFromOpaquePtr(void *P) {
0157 GlobalDecl GD;
0158 GD.Value.setFromOpaqueValue(P);
0159 return GD;
0160 }
0161
0162 static KernelReferenceKind getDefaultKernelReference(const FunctionDecl *D) {
0163 return D->getLangOpts().CUDAIsDevice ? KernelReferenceKind::Kernel
0164 : KernelReferenceKind::Stub;
0165 }
0166
0167 GlobalDecl getWithDecl(const Decl *D) {
0168 GlobalDecl Result(*this);
0169 Result.Value.setPointer(D);
0170 return Result;
0171 }
0172
0173 GlobalDecl getWithCtorType(CXXCtorType Type) {
0174 assert(isa<CXXConstructorDecl>(getDecl()));
0175 GlobalDecl Result(*this);
0176 Result.Value.setInt(Type);
0177 return Result;
0178 }
0179
0180 GlobalDecl getWithDtorType(CXXDtorType Type) {
0181 assert(isa<CXXDestructorDecl>(getDecl()));
0182 GlobalDecl Result(*this);
0183 Result.Value.setInt(Type);
0184 return Result;
0185 }
0186
0187 GlobalDecl getWithMultiVersionIndex(unsigned Index) {
0188 assert(isa<FunctionDecl>(getDecl()) &&
0189 !cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
0190 !isa<CXXConstructorDecl>(getDecl()) &&
0191 !isa<CXXDestructorDecl>(getDecl()) &&
0192 "Decl is not a plain FunctionDecl!");
0193 GlobalDecl Result(*this);
0194 Result.MultiVersionIndex = Index;
0195 return Result;
0196 }
0197
0198 GlobalDecl getWithKernelReferenceKind(KernelReferenceKind Kind) {
0199 assert(isa<FunctionDecl>(getDecl()) &&
0200 cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
0201 "Decl is not a GPU kernel!");
0202 GlobalDecl Result(*this);
0203 Result.Value.setInt(unsigned(Kind));
0204 return Result;
0205 }
0206 };
0207
0208 }
0209
0210 namespace llvm {
0211
0212 template<> struct DenseMapInfo<clang::GlobalDecl> {
0213 static inline clang::GlobalDecl getEmptyKey() {
0214 return clang::GlobalDecl();
0215 }
0216
0217 static inline clang::GlobalDecl getTombstoneKey() {
0218 return clang::GlobalDecl::
0219 getFromOpaquePtr(reinterpret_cast<void*>(-1));
0220 }
0221
0222 static unsigned getHashValue(clang::GlobalDecl GD) {
0223 return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
0224 }
0225
0226 static bool isEqual(clang::GlobalDecl LHS,
0227 clang::GlobalDecl RHS) {
0228 return LHS == RHS;
0229 }
0230 };
0231
0232 }
0233
0234 #endif