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); }
44764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
45764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
46764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
47764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  : Value(D, Type) {}
48764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
49764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  : Value(D, Type) {}
50764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
51dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson  GlobalDecl getCanonicalDecl() const {
52dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson    GlobalDecl CanonGD;
53dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson    CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
54dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson    CanonGD.Value.setInt(Value.getInt());
55dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson
56dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson    return CanonGD;
57dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson  }
58dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson
59764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  const Decl *getDecl() const { return Value.getPointer(); }
60764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
61764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  CXXCtorType getCtorType() const {
62764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
63764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    return static_cast<CXXCtorType>(Value.getInt());
64764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  }
65764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
66764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  CXXDtorType getDtorType() const {
67764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
68764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    return static_cast<CXXDtorType>(Value.getInt());
69764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  }
70764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
71764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
72764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    return LHS.Value == RHS.Value;
73764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  }
74764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
75764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
76764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
77764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  static GlobalDecl getFromOpaquePtr(void *P) {
78764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    GlobalDecl GD;
79764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    GD.Value.setFromOpaqueValue(P);
80764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    return GD;
81764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  }
82a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor
83a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor  GlobalDecl getWithDecl(const Decl *D) {
84a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor    GlobalDecl Result(*this);
85a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor    Result.Value.setPointer(D);
86a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor    return Result;
87a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor  }
88764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson};
89764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
90764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson} // end namespace clang
91764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
92764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlssonnamespace llvm {
93764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  template<class> struct DenseMapInfo;
94764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
95fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne  template<> struct DenseMapInfo<clang::GlobalDecl> {
96fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne    static inline clang::GlobalDecl getEmptyKey() {
97fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne      return clang::GlobalDecl();
98764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    }
99764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
100fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne    static inline clang::GlobalDecl getTombstoneKey() {
101fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne      return clang::GlobalDecl::
102764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson        getFromOpaquePtr(reinterpret_cast<void*>(-1));
103764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    }
104764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
105fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne    static unsigned getHashValue(clang::GlobalDecl GD) {
106764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson      return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
107764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    }
108764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
109fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne    static bool isEqual(clang::GlobalDecl LHS,
110fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne                        clang::GlobalDecl RHS) {
111764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson      return LHS == RHS;
112764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    }
113764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
114764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  };
115764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
11606159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner  // GlobalDecl isn't *technically* a POD type. However, its copy constructor,
11706159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner  // copy assignment operator, and destructor are all trivial.
11806159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner  template <>
119fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne  struct isPodLike<clang::GlobalDecl> {
12006159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner    static const bool value = true;
12106159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner  };
12206159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner} // end namespace llvm
123764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
124764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson#endif
125