Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:37

0001 //===- GlobalDecl.h - Global declaration holder -----------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor
0010 // together with its type.
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 /// GlobalDecl - represents a global declaration. This can either be a
0045 /// CXXConstructorDecl and the constructor type (Base, Complete).
0046 /// a CXXDestructorDecl and the destructor type (Base, Complete),
0047 /// a FunctionDecl and the kernel reference type (Kernel, Stub), or
0048 /// a VarDecl, a FunctionDecl or a BlockDecl.
0049 ///
0050 /// When a new type of GlobalDecl is added, the following places should
0051 /// be updated to convert a Decl* to a GlobalDecl:
0052 /// PredefinedExpr::ComputeName() in lib/AST/Expr.cpp.
0053 /// getParentOfLocalEntity() in lib/AST/ItaniumMangle.cpp
0054 /// ASTNameGenerator::Implementation::writeFuncOrVarName in lib/AST/Mangle.cpp
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 } // namespace clang
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 } // namespace llvm
0233 
0234 #endif // LLVM_CLANG_AST_GLOBALDECL_H