blob: b812020f2aa4503e718875bcf3a4f95f45d72482 [file] [log] [blame]
Anders Carlsson764d0c22009-11-13 04:25:07 +00001//===--- 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 CLANG_CODEGEN_GLOBALDECL_H
16#define CLANG_CODEGEN_GLOBALDECL_H
17
18namespace clang {
19
20namespace CodeGen {
21
22/// GlobalDecl - represents a global declaration. This can either be a
23/// CXXConstructorDecl and the constructor type (Base, Complete).
24/// a CXXDestructorDecl and the destructor type (Base, Complete) or
25/// a VarDecl, a FunctionDecl or a BlockDecl.
26class GlobalDecl {
27 llvm::PointerIntPair<const Decl*, 2> Value;
28
29 void Init(const Decl *D) {
30 assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
31 assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
32
33 Value.setPointer(D);
34 }
35
36public:
37 GlobalDecl() {}
38
39 GlobalDecl(const VarDecl *D) { Init(D);}
40 GlobalDecl(const FunctionDecl *D) { Init(D); }
41 GlobalDecl(const BlockDecl *D) { Init(D); }
42 GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
43
44 GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
45 : Value(D, Type) {}
46 GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
47 : Value(D, Type) {}
48
49 const Decl *getDecl() const { return Value.getPointer(); }
50
51 CXXCtorType getCtorType() const {
52 assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
53 return static_cast<CXXCtorType>(Value.getInt());
54 }
55
56 CXXDtorType getDtorType() const {
57 assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
58 return static_cast<CXXDtorType>(Value.getInt());
59 }
60
61 friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
62 return LHS.Value == RHS.Value;
63 }
64
65 void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
66
67 static GlobalDecl getFromOpaquePtr(void *P) {
68 GlobalDecl GD;
69 GD.Value.setFromOpaqueValue(P);
70 return GD;
71 }
72};
73
74} // end namespace CodeGen
75} // end namespace clang
76
77namespace llvm {
78 template<class> struct DenseMapInfo;
79
80 template<> struct DenseMapInfo<clang::CodeGen::GlobalDecl> {
81 static inline clang::CodeGen::GlobalDecl getEmptyKey() {
82 return clang::CodeGen::GlobalDecl();
83 }
84
85 static inline clang::CodeGen::GlobalDecl getTombstoneKey() {
86 return clang::CodeGen::GlobalDecl::
87 getFromOpaquePtr(reinterpret_cast<void*>(-1));
88 }
89
90 static unsigned getHashValue(clang::CodeGen::GlobalDecl GD) {
91 return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
92 }
93
94 static bool isEqual(clang::CodeGen::GlobalDecl LHS,
95 clang::CodeGen::GlobalDecl RHS) {
96 return LHS == RHS;
97 }
98
99 static bool isPod() {
100 // GlobalDecl isn't *technically* a POD type. However, we can get
101 // away with calling it a POD type since its copy constructor,
102 // copy assignment operator, and destructor are all trivial.
103 return true;
104 }
105
106 };
107
108}
109
110#endif