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/Basic/ABI.h" 21 22 namespace clang { 23 24 /// GlobalDecl - represents a global declaration. This can either be a 25 /// CXXConstructorDecl and the constructor type (Base, Complete). 26 /// a CXXDestructorDecl and the destructor type (Base, Complete) or 27 /// a VarDecl, a FunctionDecl or a BlockDecl. 28 class GlobalDecl { 29 llvm::PointerIntPair<const Decl*, 2> Value; 30 31 void Init(const Decl *D) { 32 assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!"); 33 assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!"); 34 35 Value.setPointer(D); 36 } 37 38 public: 39 GlobalDecl() {} 40 41 GlobalDecl(const VarDecl *D) { Init(D);} 42 GlobalDecl(const FunctionDecl *D) { Init(D); } 43 GlobalDecl(const BlockDecl *D) { Init(D); } 44 GlobalDecl(const ObjCMethodDecl *D) { Init(D); } 45 46 GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) 47 : Value(D, Type) {} 48 GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) 49 : Value(D, Type) {} 50 51 GlobalDecl getCanonicalDecl() const { 52 GlobalDecl CanonGD; 53 CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl()); 54 CanonGD.Value.setInt(Value.getInt()); 55 56 return CanonGD; 57 } 58 59 const Decl *getDecl() const { return Value.getPointer(); } 60 61 CXXCtorType getCtorType() const { 62 assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!"); 63 return static_cast<CXXCtorType>(Value.getInt()); 64 } 65 66 CXXDtorType getDtorType() const { 67 assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!"); 68 return static_cast<CXXDtorType>(Value.getInt()); 69 } 70 71 friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) { 72 return LHS.Value == RHS.Value; 73 } 74 75 void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } 76 77 static GlobalDecl getFromOpaquePtr(void *P) { 78 GlobalDecl GD; 79 GD.Value.setFromOpaqueValue(P); 80 return GD; 81 } 82 83 GlobalDecl getWithDecl(const Decl *D) { 84 GlobalDecl Result(*this); 85 Result.Value.setPointer(D); 86 return Result; 87 } 88 }; 89 90 } // end namespace clang 91 92 namespace llvm { 93 template<class> struct DenseMapInfo; 94 95 template<> struct DenseMapInfo<clang::GlobalDecl> { 96 static inline clang::GlobalDecl getEmptyKey() { 97 return clang::GlobalDecl(); 98 } 99 100 static inline clang::GlobalDecl getTombstoneKey() { 101 return clang::GlobalDecl:: 102 getFromOpaquePtr(reinterpret_cast<void*>(-1)); 103 } 104 105 static unsigned getHashValue(clang::GlobalDecl GD) { 106 return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr()); 107 } 108 109 static bool isEqual(clang::GlobalDecl LHS, 110 clang::GlobalDecl RHS) { 111 return LHS == RHS; 112 } 113 114 }; 115 116 // GlobalDecl isn't *technically* a POD type. However, its copy constructor, 117 // copy assignment operator, and destructor are all trivial. 118 template <> 119 struct isPodLike<clang::GlobalDecl> { 120 static const bool value = true; 121 }; 122 } // end namespace llvm 123 124 #endif 125