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 OMPDeclareMapperDecl *D) { Init(D); }
63 GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {}
64 GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {}
65 GlobalDecl(const VarDecl *D, DynamicInitKind StubKind)
66 : Value(D, unsigned(StubKind)) {}
68 GlobalDecl getCanonicalDecl() const {
70 CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
71 CanonGD.Value.setInt(Value.getInt());
72 CanonGD.MultiVersionIndex = MultiVersionIndex;
77 const Decl *getDecl() const { return Value.getPointer(); }
79 CXXCtorType getCtorType() const {
80 assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
81 return static_cast<CXXCtorType>(Value.getInt());
84 CXXDtorType getDtorType() const {
85 assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
86 return static_cast<CXXDtorType>(Value.getInt());
89 DynamicInitKind getDynamicInitKind() const {
90 assert(isa<VarDecl>(getDecl()) &&
91 cast<VarDecl>(getDecl())->hasGlobalStorage() &&
92 "Decl is not a global variable!");
93 return static_cast<DynamicInitKind>(Value.getInt());
96 unsigned getMultiVersionIndex() const {
97 assert(isa<FunctionDecl>(getDecl()) &&
98 !isa<CXXConstructorDecl>(getDecl()) &&
99 !isa<CXXDestructorDecl>(getDecl()) &&
100 "Decl is not a plain FunctionDecl!");
101 return MultiVersionIndex;
104 friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
105 return LHS.Value == RHS.Value &&
106 LHS.MultiVersionIndex == RHS.MultiVersionIndex;
109 void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
111 static GlobalDecl getFromOpaquePtr(void *P) {
113 GD.Value.setFromOpaqueValue(P);
117 GlobalDecl getWithDecl(const Decl *D) {
118 GlobalDecl Result(*this);
119 Result.Value.setPointer(D);
123 GlobalDecl getWithCtorType(CXXCtorType Type) {
124 assert(isa<CXXConstructorDecl>(getDecl()));
125 GlobalDecl Result(*this);
126 Result.Value.setInt(Type);
130 GlobalDecl getWithDtorType(CXXDtorType Type) {
131 assert(isa<CXXDestructorDecl>(getDecl()));
132 GlobalDecl Result(*this);
133 Result.Value.setInt(Type);
137 GlobalDecl getWithMultiVersionIndex(unsigned Index) {
138 assert(isa<FunctionDecl>(getDecl()) &&
139 !isa<CXXConstructorDecl>(getDecl()) &&
140 !isa<CXXDestructorDecl>(getDecl()) &&
141 "Decl is not a plain FunctionDecl!");
142 GlobalDecl Result(*this);
143 Result.MultiVersionIndex = Index;
152 template<> struct DenseMapInfo<clang::GlobalDecl> {
153 static inline clang::GlobalDecl getEmptyKey() {
154 return clang::GlobalDecl();
157 static inline clang::GlobalDecl getTombstoneKey() {
158 return clang::GlobalDecl::
159 getFromOpaquePtr(reinterpret_cast<void*>(-1));
162 static unsigned getHashValue(clang::GlobalDecl GD) {
163 return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
166 static bool isEqual(clang::GlobalDecl LHS,
167 clang::GlobalDecl RHS) {
174 #endif // LLVM_CLANG_AST_GLOBALDECL_H