clang API Documentation

GlobalDecl.h
Go to the documentation of this file.
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 CapturedDecl *D) { Init(D); }
00045   GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
00046 
00047   GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
00048   : Value(D, Type) {}
00049   GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
00050   : Value(D, Type) {}
00051 
00052   GlobalDecl getCanonicalDecl() const {
00053     GlobalDecl CanonGD;
00054     CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
00055     CanonGD.Value.setInt(Value.getInt());
00056     
00057     return CanonGD;
00058   }
00059 
00060   const Decl *getDecl() const { return Value.getPointer(); }
00061 
00062   CXXCtorType getCtorType() const {
00063     assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
00064     return static_cast<CXXCtorType>(Value.getInt());
00065   }
00066 
00067   CXXDtorType getDtorType() const {
00068     assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
00069     return static_cast<CXXDtorType>(Value.getInt());
00070   }
00071   
00072   friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
00073     return LHS.Value == RHS.Value;
00074   }
00075   
00076   void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
00077 
00078   static GlobalDecl getFromOpaquePtr(void *P) {
00079     GlobalDecl GD;
00080     GD.Value.setFromOpaqueValue(P);
00081     return GD;
00082   }
00083   
00084   GlobalDecl getWithDecl(const Decl *D) {
00085     GlobalDecl Result(*this);
00086     Result.Value.setPointer(D);
00087     return Result;
00088   }
00089 };
00090 
00091 } // end namespace clang
00092 
00093 namespace llvm {
00094   template<class> struct DenseMapInfo;
00095 
00096   template<> struct DenseMapInfo<clang::GlobalDecl> {
00097     static inline clang::GlobalDecl getEmptyKey() {
00098       return clang::GlobalDecl();
00099     }
00100   
00101     static inline clang::GlobalDecl getTombstoneKey() {
00102       return clang::GlobalDecl::
00103         getFromOpaquePtr(reinterpret_cast<void*>(-1));
00104     }
00105 
00106     static unsigned getHashValue(clang::GlobalDecl GD) {
00107       return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
00108     }
00109     
00110     static bool isEqual(clang::GlobalDecl LHS, 
00111                         clang::GlobalDecl RHS) {
00112       return LHS == RHS;
00113     }
00114       
00115   };
00116   
00117   // GlobalDecl isn't *technically* a POD type. However, its copy constructor,
00118   // copy assignment operator, and destructor are all trivial.
00119   template <>
00120   struct isPodLike<clang::GlobalDecl> {
00121     static const bool value = true;
00122   };
00123 } // end namespace llvm
00124 
00125 #endif