Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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