1327952Sdim//===- GlobalDecl.h - Global declaration holder -----------------*- C++ -*-===// 2224135Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6224135Sdim// 7224135Sdim//===----------------------------------------------------------------------===// 8224135Sdim// 9224135Sdim// A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor 10224135Sdim// together with its type. 11224135Sdim// 12224135Sdim//===----------------------------------------------------------------------===// 13224135Sdim 14224135Sdim#ifndef LLVM_CLANG_AST_GLOBALDECL_H 15224135Sdim#define LLVM_CLANG_AST_GLOBALDECL_H 16224135Sdim 17224135Sdim#include "clang/AST/DeclCXX.h" 18224135Sdim#include "clang/AST/DeclObjC.h" 19309124Sdim#include "clang/AST/DeclOpenMP.h" 20224135Sdim#include "clang/Basic/ABI.h" 21327952Sdim#include "clang/Basic/LLVM.h" 22327952Sdim#include "llvm/ADT/DenseMapInfo.h" 23327952Sdim#include "llvm/ADT/PointerIntPair.h" 24327952Sdim#include "llvm/Support/Casting.h" 25327952Sdim#include "llvm/Support/type_traits.h" 26327952Sdim#include <cassert> 27224135Sdim 28224135Sdimnamespace clang { 29224135Sdim 30353358Sdimenum class DynamicInitKind : unsigned { 31353358Sdim NoStub = 0, 32353358Sdim Initializer, 33353358Sdim AtExit, 34353358Sdim}; 35353358Sdim 36224135Sdim/// GlobalDecl - represents a global declaration. This can either be a 37224135Sdim/// CXXConstructorDecl and the constructor type (Base, Complete). 38224135Sdim/// a CXXDestructorDecl and the destructor type (Base, Complete) or 39224135Sdim/// a VarDecl, a FunctionDecl or a BlockDecl. 40224135Sdimclass GlobalDecl { 41327952Sdim llvm::PointerIntPair<const Decl *, 2> Value; 42344779Sdim unsigned MultiVersionIndex = 0; 43224135Sdim 44224135Sdim void Init(const Decl *D) { 45224135Sdim assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!"); 46224135Sdim assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!"); 47224135Sdim 48224135Sdim Value.setPointer(D); 49224135Sdim } 50224135Sdim 51224135Sdimpublic: 52327952Sdim GlobalDecl() = default; 53224135Sdim GlobalDecl(const VarDecl *D) { Init(D);} 54344779Sdim GlobalDecl(const FunctionDecl *D, unsigned MVIndex = 0) 55344779Sdim : MultiVersionIndex(MVIndex) { 56344779Sdim Init(D); 57344779Sdim } 58224135Sdim GlobalDecl(const BlockDecl *D) { Init(D); } 59261991Sdim GlobalDecl(const CapturedDecl *D) { Init(D); } 60224135Sdim GlobalDecl(const ObjCMethodDecl *D) { Init(D); } 61309124Sdim GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); } 62360784Sdim GlobalDecl(const OMPDeclareMapperDecl *D) { Init(D); } 63327952Sdim GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {} 64327952Sdim GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {} 65353358Sdim GlobalDecl(const VarDecl *D, DynamicInitKind StubKind) 66353358Sdim : Value(D, unsigned(StubKind)) {} 67224135Sdim 68224135Sdim GlobalDecl getCanonicalDecl() const { 69224135Sdim GlobalDecl CanonGD; 70224135Sdim CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl()); 71224135Sdim CanonGD.Value.setInt(Value.getInt()); 72344779Sdim CanonGD.MultiVersionIndex = MultiVersionIndex; 73341825Sdim 74224135Sdim return CanonGD; 75224135Sdim } 76224135Sdim 77224135Sdim const Decl *getDecl() const { return Value.getPointer(); } 78224135Sdim 79224135Sdim CXXCtorType getCtorType() const { 80224135Sdim assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!"); 81224135Sdim return static_cast<CXXCtorType>(Value.getInt()); 82224135Sdim } 83224135Sdim 84224135Sdim CXXDtorType getDtorType() const { 85224135Sdim assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!"); 86224135Sdim return static_cast<CXXDtorType>(Value.getInt()); 87224135Sdim } 88341825Sdim 89353358Sdim DynamicInitKind getDynamicInitKind() const { 90353358Sdim assert(isa<VarDecl>(getDecl()) && 91353358Sdim cast<VarDecl>(getDecl())->hasGlobalStorage() && 92353358Sdim "Decl is not a global variable!"); 93353358Sdim return static_cast<DynamicInitKind>(Value.getInt()); 94353358Sdim } 95353358Sdim 96344779Sdim unsigned getMultiVersionIndex() const { 97344779Sdim assert(isa<FunctionDecl>(getDecl()) && 98344779Sdim !isa<CXXConstructorDecl>(getDecl()) && 99344779Sdim !isa<CXXDestructorDecl>(getDecl()) && 100344779Sdim "Decl is not a plain FunctionDecl!"); 101344779Sdim return MultiVersionIndex; 102344779Sdim } 103344779Sdim 104224135Sdim friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) { 105344779Sdim return LHS.Value == RHS.Value && 106344779Sdim LHS.MultiVersionIndex == RHS.MultiVersionIndex; 107224135Sdim } 108341825Sdim 109224135Sdim void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } 110224135Sdim 111224135Sdim static GlobalDecl getFromOpaquePtr(void *P) { 112224135Sdim GlobalDecl GD; 113224135Sdim GD.Value.setFromOpaqueValue(P); 114224135Sdim return GD; 115224135Sdim } 116341825Sdim 117224135Sdim GlobalDecl getWithDecl(const Decl *D) { 118224135Sdim GlobalDecl Result(*this); 119224135Sdim Result.Value.setPointer(D); 120224135Sdim return Result; 121224135Sdim } 122344779Sdim 123353358Sdim GlobalDecl getWithCtorType(CXXCtorType Type) { 124353358Sdim assert(isa<CXXConstructorDecl>(getDecl())); 125353358Sdim GlobalDecl Result(*this); 126353358Sdim Result.Value.setInt(Type); 127353358Sdim return Result; 128353358Sdim } 129353358Sdim 130353358Sdim GlobalDecl getWithDtorType(CXXDtorType Type) { 131353358Sdim assert(isa<CXXDestructorDecl>(getDecl())); 132353358Sdim GlobalDecl Result(*this); 133353358Sdim Result.Value.setInt(Type); 134353358Sdim return Result; 135353358Sdim } 136353358Sdim 137344779Sdim GlobalDecl getWithMultiVersionIndex(unsigned Index) { 138344779Sdim assert(isa<FunctionDecl>(getDecl()) && 139344779Sdim !isa<CXXConstructorDecl>(getDecl()) && 140344779Sdim !isa<CXXDestructorDecl>(getDecl()) && 141344779Sdim "Decl is not a plain FunctionDecl!"); 142344779Sdim GlobalDecl Result(*this); 143344779Sdim Result.MultiVersionIndex = Index; 144344779Sdim return Result; 145344779Sdim } 146224135Sdim}; 147224135Sdim 148327952Sdim} // namespace clang 149224135Sdim 150224135Sdimnamespace llvm { 151224135Sdim 152224135Sdim template<> struct DenseMapInfo<clang::GlobalDecl> { 153224135Sdim static inline clang::GlobalDecl getEmptyKey() { 154224135Sdim return clang::GlobalDecl(); 155224135Sdim } 156341825Sdim 157224135Sdim static inline clang::GlobalDecl getTombstoneKey() { 158224135Sdim return clang::GlobalDecl:: 159224135Sdim getFromOpaquePtr(reinterpret_cast<void*>(-1)); 160224135Sdim } 161224135Sdim 162224135Sdim static unsigned getHashValue(clang::GlobalDecl GD) { 163224135Sdim return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr()); 164224135Sdim } 165341825Sdim 166341825Sdim static bool isEqual(clang::GlobalDecl LHS, 167224135Sdim clang::GlobalDecl RHS) { 168224135Sdim return LHS == RHS; 169224135Sdim } 170224135Sdim }; 171341825Sdim 172327952Sdim} // namespace llvm 173327952Sdim 174327952Sdim#endif // LLVM_CLANG_AST_GLOBALDECL_H 175