clang API Documentation
00001 //===--- GlobalDecl.h - Global declaration holder ---------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor 00011 // together with its type. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_CLANG_AST_GLOBALDECL_H 00016 #define LLVM_CLANG_AST_GLOBALDECL_H 00017 00018 #include "clang/AST/DeclCXX.h" 00019 #include "clang/AST/DeclObjC.h" 00020 #include "clang/Basic/ABI.h" 00021 00022 namespace clang { 00023 00024 /// GlobalDecl - represents a global declaration. This can either be a 00025 /// CXXConstructorDecl and the constructor type (Base, Complete). 00026 /// a CXXDestructorDecl and the destructor type (Base, Complete) or 00027 /// a VarDecl, a FunctionDecl or a BlockDecl. 00028 class GlobalDecl { 00029 llvm::PointerIntPair<const Decl*, 2> Value; 00030 00031 void Init(const Decl *D) { 00032 assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!"); 00033 assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!"); 00034 00035 Value.setPointer(D); 00036 } 00037 00038 public: 00039 GlobalDecl() {} 00040 00041 GlobalDecl(const VarDecl *D) { Init(D);} 00042 GlobalDecl(const FunctionDecl *D) { Init(D); } 00043 GlobalDecl(const BlockDecl *D) { Init(D); } 00044 GlobalDecl(const ObjCMethodDecl *D) { Init(D); } 00045 00046 GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) 00047 : Value(D, Type) {} 00048 GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) 00049 : Value(D, Type) {} 00050 00051 GlobalDecl getCanonicalDecl() const { 00052 GlobalDecl CanonGD; 00053 CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl()); 00054 CanonGD.Value.setInt(Value.getInt()); 00055 00056 return CanonGD; 00057 } 00058 00059 const Decl *getDecl() const { return Value.getPointer(); } 00060 00061 CXXCtorType getCtorType() const { 00062 assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!"); 00063 return static_cast<CXXCtorType>(Value.getInt()); 00064 } 00065 00066 CXXDtorType getDtorType() const { 00067 assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!"); 00068 return static_cast<CXXDtorType>(Value.getInt()); 00069 } 00070 00071 friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) { 00072 return LHS.Value == RHS.Value; 00073 } 00074 00075 void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } 00076 00077 static GlobalDecl getFromOpaquePtr(void *P) { 00078 GlobalDecl GD; 00079 GD.Value.setFromOpaqueValue(P); 00080 return GD; 00081 } 00082 00083 GlobalDecl getWithDecl(const Decl *D) { 00084 GlobalDecl Result(*this); 00085 Result.Value.setPointer(D); 00086 return Result; 00087 } 00088 }; 00089 00090 } // end namespace clang 00091 00092 namespace llvm { 00093 template<class> struct DenseMapInfo; 00094 00095 template<> struct DenseMapInfo<clang::GlobalDecl> { 00096 static inline clang::GlobalDecl getEmptyKey() { 00097 return clang::GlobalDecl(); 00098 } 00099 00100 static inline clang::GlobalDecl getTombstoneKey() { 00101 return clang::GlobalDecl:: 00102 getFromOpaquePtr(reinterpret_cast<void*>(-1)); 00103 } 00104 00105 static unsigned getHashValue(clang::GlobalDecl GD) { 00106 return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr()); 00107 } 00108 00109 static bool isEqual(clang::GlobalDecl LHS, 00110 clang::GlobalDecl RHS) { 00111 return LHS == RHS; 00112 } 00113 00114 }; 00115 00116 // GlobalDecl isn't *technically* a POD type. However, its copy constructor, 00117 // copy assignment operator, and destructor are all trivial. 00118 template <> 00119 struct isPodLike<clang::GlobalDecl> { 00120 static const bool value = true; 00121 }; 00122 } // end namespace llvm 00123 00124 #endif