1//===--- 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 LLVM_CLANG_AST_GLOBALDECL_H
16#define LLVM_CLANG_AST_GLOBALDECL_H
17
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/DeclObjC.h"
20#include "clang/AST/DeclOpenMP.h"
21#include "clang/Basic/ABI.h"
22
23namespace clang {
24
25/// GlobalDecl - represents a global declaration. This can either be a
26/// CXXConstructorDecl and the constructor type (Base, Complete).
27/// a CXXDestructorDecl and the destructor type (Base, Complete) or
28/// a VarDecl, a FunctionDecl or a BlockDecl.
29class GlobalDecl {
30  llvm::PointerIntPair<const Decl*, 2> Value;
31
32  void Init(const Decl *D) {
33    assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
34    assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
35
36    Value.setPointer(D);
37  }
38
39public:
40  GlobalDecl() {}
41
42  GlobalDecl(const VarDecl *D) { Init(D);}
43  GlobalDecl(const FunctionDecl *D) { Init(D); }
44  GlobalDecl(const BlockDecl *D) { Init(D); }
45  GlobalDecl(const CapturedDecl *D) { Init(D); }
46  GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
47  GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
48
49  GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
50  : Value(D, Type) {}
51  GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
52  : Value(D, Type) {}
53
54  GlobalDecl getCanonicalDecl() const {
55    GlobalDecl CanonGD;
56    CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
57    CanonGD.Value.setInt(Value.getInt());
58
59    return CanonGD;
60  }
61
62  const Decl *getDecl() const { return Value.getPointer(); }
63
64  CXXCtorType getCtorType() const {
65    assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
66    return static_cast<CXXCtorType>(Value.getInt());
67  }
68
69  CXXDtorType getDtorType() const {
70    assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
71    return static_cast<CXXDtorType>(Value.getInt());
72  }
73
74  friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
75    return LHS.Value == RHS.Value;
76  }
77
78  void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
79
80  static GlobalDecl getFromOpaquePtr(void *P) {
81    GlobalDecl GD;
82    GD.Value.setFromOpaqueValue(P);
83    return GD;
84  }
85
86  GlobalDecl getWithDecl(const Decl *D) {
87    GlobalDecl Result(*this);
88    Result.Value.setPointer(D);
89    return Result;
90  }
91};
92
93} // end namespace clang
94
95namespace llvm {
96  template<class> struct DenseMapInfo;
97
98  template<> struct DenseMapInfo<clang::GlobalDecl> {
99    static inline clang::GlobalDecl getEmptyKey() {
100      return clang::GlobalDecl();
101    }
102
103    static inline clang::GlobalDecl getTombstoneKey() {
104      return clang::GlobalDecl::
105        getFromOpaquePtr(reinterpret_cast<void*>(-1));
106    }
107
108    static unsigned getHashValue(clang::GlobalDecl GD) {
109      return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
110    }
111
112    static bool isEqual(clang::GlobalDecl LHS,
113                        clang::GlobalDecl RHS) {
114      return LHS == RHS;
115    }
116
117  };
118
119  // GlobalDecl isn't *technically* a POD type. However, its copy constructor,
120  // copy assignment operator, and destructor are all trivial.
121  template <>
122  struct isPodLike<clang::GlobalDecl> {
123    static const bool value = true;
124  };
125} // end namespace llvm
126
127#endif
128