1 //===- GlobalDecl.h - Global declaration holder -----------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor
10 // together with its type.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_AST_GLOBALDECL_H
15 #define LLVM_CLANG_AST_GLOBALDECL_H
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/DeclObjC.h"
19 #include "clang/AST/DeclOpenMP.h"
20 #include "clang/Basic/ABI.h"
21 #include "clang/Basic/LLVM.h"
22 #include "llvm/ADT/DenseMapInfo.h"
23 #include "llvm/ADT/PointerIntPair.h"
24 #include "llvm/Support/Casting.h"
25 #include "llvm/Support/type_traits.h"
30 enum class DynamicInitKind : unsigned {
36 /// GlobalDecl - represents a global declaration. This can either be a
37 /// CXXConstructorDecl and the constructor type (Base, Complete).
38 /// a CXXDestructorDecl and the destructor type (Base, Complete) or
39 /// a VarDecl, a FunctionDecl or a BlockDecl.
41 llvm::PointerIntPair<const Decl *, 2> Value;
42 unsigned MultiVersionIndex = 0;
44 void Init(const Decl *D) {
45 assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
46 assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
52 GlobalDecl() = default;
53 GlobalDecl(const VarDecl *D) { Init(D);}
54 GlobalDecl(const FunctionDecl *D, unsigned MVIndex = 0)
55 : MultiVersionIndex(MVIndex) {
58 GlobalDecl(const BlockDecl *D) { Init(D); }
59 GlobalDecl(const CapturedDecl *D) { Init(D); }
60 GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
61 GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
62 GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {}
63 GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {}
64 GlobalDecl(const VarDecl *D, DynamicInitKind StubKind)
65 : Value(D, unsigned(StubKind)) {}
67 GlobalDecl getCanonicalDecl() const {
69 CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
70 CanonGD.Value.setInt(Value.getInt());
71 CanonGD.MultiVersionIndex = MultiVersionIndex;
76 const Decl *getDecl() const { return Value.getPointer(); }
78 CXXCtorType getCtorType() const {
79 assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
80 return static_cast<CXXCtorType>(Value.getInt());
83 CXXDtorType getDtorType() const {
84 assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
85 return static_cast<CXXDtorType>(Value.getInt());
88 DynamicInitKind getDynamicInitKind() const {
89 assert(isa<VarDecl>(getDecl()) &&
90 cast<VarDecl>(getDecl())->hasGlobalStorage() &&
91 "Decl is not a global variable!");
92 return static_cast<DynamicInitKind>(Value.getInt());
95 unsigned getMultiVersionIndex() const {
96 assert(isa<FunctionDecl>(getDecl()) &&
97 !isa<CXXConstructorDecl>(getDecl()) &&
98 !isa<CXXDestructorDecl>(getDecl()) &&
99 "Decl is not a plain FunctionDecl!");
100 return MultiVersionIndex;
103 friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
104 return LHS.Value == RHS.Value &&
105 LHS.MultiVersionIndex == RHS.MultiVersionIndex;
108 void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
110 static GlobalDecl getFromOpaquePtr(void *P) {
112 GD.Value.setFromOpaqueValue(P);
116 GlobalDecl getWithDecl(const Decl *D) {
117 GlobalDecl Result(*this);
118 Result.Value.setPointer(D);
122 GlobalDecl getWithCtorType(CXXCtorType Type) {
123 assert(isa<CXXConstructorDecl>(getDecl()));
124 GlobalDecl Result(*this);
125 Result.Value.setInt(Type);
129 GlobalDecl getWithDtorType(CXXDtorType Type) {
130 assert(isa<CXXDestructorDecl>(getDecl()));
131 GlobalDecl Result(*this);
132 Result.Value.setInt(Type);
136 GlobalDecl getWithMultiVersionIndex(unsigned Index) {
137 assert(isa<FunctionDecl>(getDecl()) &&
138 !isa<CXXConstructorDecl>(getDecl()) &&
139 !isa<CXXDestructorDecl>(getDecl()) &&
140 "Decl is not a plain FunctionDecl!");
141 GlobalDecl Result(*this);
142 Result.MultiVersionIndex = Index;
151 template<> struct DenseMapInfo<clang::GlobalDecl> {
152 static inline clang::GlobalDecl getEmptyKey() {
153 return clang::GlobalDecl();
156 static inline clang::GlobalDecl getTombstoneKey() {
157 return clang::GlobalDecl::
158 getFromOpaquePtr(reinterpret_cast<void*>(-1));
161 static unsigned getHashValue(clang::GlobalDecl GD) {
162 return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
165 static bool isEqual(clang::GlobalDecl LHS,
166 clang::GlobalDecl RHS) {
173 #endif // LLVM_CLANG_AST_GLOBALDECL_H