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 23 namespace 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. 29 class GlobalDecl { 30 llvm::PointerIntPair<const Decl*, 2> Value; 31 Init(const Decl * D)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 39 public: GlobalDecl()40 GlobalDecl() {} 41 GlobalDecl(const VarDecl * D)42 GlobalDecl(const VarDecl *D) { Init(D);} GlobalDecl(const FunctionDecl * D)43 GlobalDecl(const FunctionDecl *D) { Init(D); } GlobalDecl(const BlockDecl * D)44 GlobalDecl(const BlockDecl *D) { Init(D); } GlobalDecl(const CapturedDecl * D)45 GlobalDecl(const CapturedDecl *D) { Init(D); } GlobalDecl(const ObjCMethodDecl * D)46 GlobalDecl(const ObjCMethodDecl *D) { Init(D); } GlobalDecl(const OMPDeclareReductionDecl * D)47 GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); } 48 GlobalDecl(const CXXConstructorDecl * D,CXXCtorType Type)49 GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) 50 : Value(D, Type) {} GlobalDecl(const CXXDestructorDecl * D,CXXDtorType Type)51 GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) 52 : Value(D, Type) {} 53 getCanonicalDecl()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 getDecl()62 const Decl *getDecl() const { return Value.getPointer(); } 63 getCtorType()64 CXXCtorType getCtorType() const { 65 assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!"); 66 return static_cast<CXXCtorType>(Value.getInt()); 67 } 68 getDtorType()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 getAsOpaquePtr()78 void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } 79 getFromOpaquePtr(void * P)80 static GlobalDecl getFromOpaquePtr(void *P) { 81 GlobalDecl GD; 82 GD.Value.setFromOpaqueValue(P); 83 return GD; 84 } 85 getWithDecl(const Decl * D)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 95 namespace 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