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 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