1//===--- GlobalDecl.h - Global declaration holder ---------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor 11// together with its type. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_CLANG_AST_GLOBALDECL_H 16#define LLVM_CLANG_AST_GLOBALDECL_H 17 18#include "clang/AST/DeclCXX.h" 19#include "clang/AST/DeclObjC.h" 20#include "clang/AST/DeclOpenMP.h" 21#include "clang/Basic/ABI.h" 22 23namespace clang { 24 25/// GlobalDecl - represents a global declaration. This can either be a 26/// CXXConstructorDecl and the constructor type (Base, Complete). 27/// a CXXDestructorDecl and the destructor type (Base, Complete) or 28/// a VarDecl, a FunctionDecl or a BlockDecl. 29class GlobalDecl { 30 llvm::PointerIntPair<const Decl*, 2> Value; 31 32 void Init(const Decl *D) { 33 assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!"); 34 assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!"); 35 36 Value.setPointer(D); 37 } 38 39public: 40 GlobalDecl() {} 41 42 GlobalDecl(const VarDecl *D) { Init(D);} 43 GlobalDecl(const FunctionDecl *D) { Init(D); } 44 GlobalDecl(const BlockDecl *D) { Init(D); } 45 GlobalDecl(const CapturedDecl *D) { Init(D); } 46 GlobalDecl(const ObjCMethodDecl *D) { Init(D); } 47 GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); } 48 49 GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) 50 : Value(D, Type) {} 51 GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) 52 : Value(D, Type) {} 53 54 GlobalDecl getCanonicalDecl() const { 55 GlobalDecl CanonGD; 56 CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl()); 57 CanonGD.Value.setInt(Value.getInt()); 58 59 return CanonGD; 60 } 61 62 const Decl *getDecl() const { return Value.getPointer(); } 63 64 CXXCtorType getCtorType() const { 65 assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!"); 66 return static_cast<CXXCtorType>(Value.getInt()); 67 } 68 69 CXXDtorType getDtorType() const { 70 assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!"); 71 return static_cast<CXXDtorType>(Value.getInt()); 72 } 73 74 friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) { 75 return LHS.Value == RHS.Value; 76 } 77 78 void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } 79 80 static GlobalDecl getFromOpaquePtr(void *P) { 81 GlobalDecl GD; 82 GD.Value.setFromOpaqueValue(P); 83 return GD; 84 } 85 86 GlobalDecl getWithDecl(const Decl *D) { 87 GlobalDecl Result(*this); 88 Result.Value.setPointer(D); 89 return Result; 90 } 91}; 92 93} // end namespace clang 94 95namespace llvm { 96 template<class> struct DenseMapInfo; 97 98 template<> struct DenseMapInfo<clang::GlobalDecl> { 99 static inline clang::GlobalDecl getEmptyKey() { 100 return clang::GlobalDecl(); 101 } 102 103 static inline clang::GlobalDecl getTombstoneKey() { 104 return clang::GlobalDecl:: 105 getFromOpaquePtr(reinterpret_cast<void*>(-1)); 106 } 107 108 static unsigned getHashValue(clang::GlobalDecl GD) { 109 return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr()); 110 } 111 112 static bool isEqual(clang::GlobalDecl LHS, 113 clang::GlobalDecl RHS) { 114 return LHS == RHS; 115 } 116 117 }; 118 119 // GlobalDecl isn't *technically* a POD type. However, its copy constructor, 120 // copy assignment operator, and destructor are all trivial. 121 template <> 122 struct isPodLike<clang::GlobalDecl> { 123 static const bool value = true; 124 }; 125} // end namespace llvm 126 127#endif 128