1224135Sdim//===--- GlobalDecl.h - Global declaration holder ---------------*- C++ -*-===// 2224135Sdim// 3224135Sdim// The LLVM Compiler Infrastructure 4224135Sdim// 5224135Sdim// This file is distributed under the University of Illinois Open Source 6224135Sdim// License. See LICENSE.TXT for details. 7224135Sdim// 8224135Sdim//===----------------------------------------------------------------------===// 9224135Sdim// 10224135Sdim// A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor 11224135Sdim// together with its type. 12224135Sdim// 13224135Sdim//===----------------------------------------------------------------------===// 14224135Sdim 15224135Sdim#ifndef LLVM_CLANG_AST_GLOBALDECL_H 16224135Sdim#define LLVM_CLANG_AST_GLOBALDECL_H 17224135Sdim 18224135Sdim#include "clang/AST/DeclCXX.h" 19224135Sdim#include "clang/AST/DeclObjC.h" 20224135Sdim#include "clang/Basic/ABI.h" 21224135Sdim 22224135Sdimnamespace clang { 23224135Sdim 24224135Sdim/// GlobalDecl - represents a global declaration. This can either be a 25224135Sdim/// CXXConstructorDecl and the constructor type (Base, Complete). 26224135Sdim/// a CXXDestructorDecl and the destructor type (Base, Complete) or 27224135Sdim/// a VarDecl, a FunctionDecl or a BlockDecl. 28224135Sdimclass GlobalDecl { 29224135Sdim llvm::PointerIntPair<const Decl*, 2> Value; 30224135Sdim 31224135Sdim void Init(const Decl *D) { 32224135Sdim assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!"); 33224135Sdim assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!"); 34224135Sdim 35224135Sdim Value.setPointer(D); 36224135Sdim } 37224135Sdim 38224135Sdimpublic: 39224135Sdim GlobalDecl() {} 40224135Sdim 41224135Sdim GlobalDecl(const VarDecl *D) { Init(D);} 42224135Sdim GlobalDecl(const FunctionDecl *D) { Init(D); } 43224135Sdim GlobalDecl(const BlockDecl *D) { Init(D); } 44263508Sdim GlobalDecl(const CapturedDecl *D) { Init(D); } 45224135Sdim GlobalDecl(const ObjCMethodDecl *D) { Init(D); } 46224135Sdim 47224135Sdim GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) 48224135Sdim : Value(D, Type) {} 49224135Sdim GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) 50224135Sdim : Value(D, Type) {} 51224135Sdim 52224135Sdim GlobalDecl getCanonicalDecl() const { 53224135Sdim GlobalDecl CanonGD; 54224135Sdim CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl()); 55224135Sdim CanonGD.Value.setInt(Value.getInt()); 56224135Sdim 57224135Sdim return CanonGD; 58224135Sdim } 59224135Sdim 60224135Sdim const Decl *getDecl() const { return Value.getPointer(); } 61224135Sdim 62224135Sdim CXXCtorType getCtorType() const { 63224135Sdim assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!"); 64224135Sdim return static_cast<CXXCtorType>(Value.getInt()); 65224135Sdim } 66224135Sdim 67224135Sdim CXXDtorType getDtorType() const { 68224135Sdim assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!"); 69224135Sdim return static_cast<CXXDtorType>(Value.getInt()); 70224135Sdim } 71224135Sdim 72224135Sdim friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) { 73224135Sdim return LHS.Value == RHS.Value; 74224135Sdim } 75224135Sdim 76224135Sdim void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } 77224135Sdim 78224135Sdim static GlobalDecl getFromOpaquePtr(void *P) { 79224135Sdim GlobalDecl GD; 80224135Sdim GD.Value.setFromOpaqueValue(P); 81224135Sdim return GD; 82224135Sdim } 83224135Sdim 84224135Sdim GlobalDecl getWithDecl(const Decl *D) { 85224135Sdim GlobalDecl Result(*this); 86224135Sdim Result.Value.setPointer(D); 87224135Sdim return Result; 88224135Sdim } 89224135Sdim}; 90224135Sdim 91224135Sdim} // end namespace clang 92224135Sdim 93224135Sdimnamespace llvm { 94224135Sdim template<class> struct DenseMapInfo; 95224135Sdim 96224135Sdim template<> struct DenseMapInfo<clang::GlobalDecl> { 97224135Sdim static inline clang::GlobalDecl getEmptyKey() { 98224135Sdim return clang::GlobalDecl(); 99224135Sdim } 100224135Sdim 101224135Sdim static inline clang::GlobalDecl getTombstoneKey() { 102224135Sdim return clang::GlobalDecl:: 103224135Sdim getFromOpaquePtr(reinterpret_cast<void*>(-1)); 104224135Sdim } 105224135Sdim 106224135Sdim static unsigned getHashValue(clang::GlobalDecl GD) { 107224135Sdim return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr()); 108224135Sdim } 109224135Sdim 110224135Sdim static bool isEqual(clang::GlobalDecl LHS, 111224135Sdim clang::GlobalDecl RHS) { 112224135Sdim return LHS == RHS; 113224135Sdim } 114224135Sdim 115224135Sdim }; 116224135Sdim 117224135Sdim // GlobalDecl isn't *technically* a POD type. However, its copy constructor, 118224135Sdim // copy assignment operator, and destructor are all trivial. 119224135Sdim template <> 120224135Sdim struct isPodLike<clang::GlobalDecl> { 121224135Sdim static const bool value = true; 122224135Sdim }; 123224135Sdim} // end namespace llvm 124224135Sdim 125224135Sdim#endif 126