1764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson//===--- GlobalDecl.h - Global declaration holder ---------------*- C++ -*-===//
2764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson//
3764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson//                     The LLVM Compiler Infrastructure
4764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson//
5764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson// This file is distributed under the University of Illinois Open Source
6764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson// License. See LICENSE.TXT for details.
7764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson//
8764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson//===----------------------------------------------------------------------===//
9764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson//
10764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson// A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor
11764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson// together with its type.
12764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson//
13764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson//===----------------------------------------------------------------------===//
14764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
15fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne#ifndef LLVM_CLANG_AST_GLOBALDECL_H
16fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne#define LLVM_CLANG_AST_GLOBALDECL_H
17764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
18b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson#include "clang/AST/DeclCXX.h"
19b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson#include "clang/AST/DeclObjC.h"
2014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "clang/Basic/ABI.h"
21b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson
22764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlssonnamespace clang {
23764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
24764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson/// GlobalDecl - represents a global declaration. This can either be a
25764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson/// CXXConstructorDecl and the constructor type (Base, Complete).
26764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson/// a CXXDestructorDecl and the destructor type (Base, Complete) or
27764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson/// a VarDecl, a FunctionDecl or a BlockDecl.
28764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlssonclass GlobalDecl {
29764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  llvm::PointerIntPair<const Decl*, 2> Value;
30764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
31764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  void Init(const Decl *D) {
32764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
33764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
34764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
35764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    Value.setPointer(D);
36764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  }
37dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson
38764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlssonpublic:
39764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  GlobalDecl() {}
40764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
41764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  GlobalDecl(const VarDecl *D) { Init(D);}
42764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  GlobalDecl(const FunctionDecl *D) { Init(D); }
43764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  GlobalDecl(const BlockDecl *D) { Init(D); }
44524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  GlobalDecl(const CapturedDecl *D) { Init(D); }
45764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
46764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
47764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
48764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  : Value(D, Type) {}
49764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
50764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  : Value(D, Type) {}
51764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
52dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson  GlobalDecl getCanonicalDecl() const {
53dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson    GlobalDecl CanonGD;
54dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson    CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
55dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson    CanonGD.Value.setInt(Value.getInt());
56dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson
57dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson    return CanonGD;
58dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson  }
59dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson
60764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  const Decl *getDecl() const { return Value.getPointer(); }
61764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
62764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  CXXCtorType getCtorType() const {
63764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
64764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    return static_cast<CXXCtorType>(Value.getInt());
65764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  }
66764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
67764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  CXXDtorType getDtorType() const {
68764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
69764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    return static_cast<CXXDtorType>(Value.getInt());
70764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  }
71764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
72764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
73764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    return LHS.Value == RHS.Value;
74764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  }
75764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
76764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
77764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
78764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  static GlobalDecl getFromOpaquePtr(void *P) {
79764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    GlobalDecl GD;
80764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    GD.Value.setFromOpaqueValue(P);
81764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    return GD;
82764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  }
83a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor
84a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor  GlobalDecl getWithDecl(const Decl *D) {
85a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor    GlobalDecl Result(*this);
86a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor    Result.Value.setPointer(D);
87a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor    return Result;
88a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor  }
89764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson};
90764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
91764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson} // end namespace clang
92764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
93764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlssonnamespace llvm {
94764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  template<class> struct DenseMapInfo;
95764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
96fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne  template<> struct DenseMapInfo<clang::GlobalDecl> {
97fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne    static inline clang::GlobalDecl getEmptyKey() {
98fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne      return clang::GlobalDecl();
99764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    }
100764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
101fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne    static inline clang::GlobalDecl getTombstoneKey() {
102fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne      return clang::GlobalDecl::
103764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson        getFromOpaquePtr(reinterpret_cast<void*>(-1));
104764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    }
105764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
106fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne    static unsigned getHashValue(clang::GlobalDecl GD) {
107764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson      return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
108764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    }
109764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
110fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne    static bool isEqual(clang::GlobalDecl LHS,
111fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne                        clang::GlobalDecl RHS) {
112764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson      return LHS == RHS;
113764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    }
114764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
115764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  };
116764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
11706159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner  // GlobalDecl isn't *technically* a POD type. However, its copy constructor,
11806159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner  // copy assignment operator, and destructor are all trivial.
11906159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner  template <>
120fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne  struct isPodLike<clang::GlobalDecl> {
12106159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner    static const bool value = true;
12206159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner  };
12306159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner} // end namespace llvm
124764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
125764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson#endif
126