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"
204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/AST/DeclOpenMP.h"
2114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "clang/Basic/ABI.h"
22b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson
23764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlssonnamespace clang {
24764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
25764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson/// GlobalDecl - represents a global declaration. This can either be a
26764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson/// CXXConstructorDecl and the constructor type (Base, Complete).
27764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson/// a CXXDestructorDecl and the destructor type (Base, Complete) or
28764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson/// a VarDecl, a FunctionDecl or a BlockDecl.
29764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlssonclass GlobalDecl {
30764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  llvm::PointerIntPair<const Decl*, 2> Value;
31764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
32764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  void Init(const Decl *D) {
33764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
34764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
35764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
36764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    Value.setPointer(D);
37764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  }
38dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson
39764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlssonpublic:
40764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  GlobalDecl() {}
41764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
42764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  GlobalDecl(const VarDecl *D) { Init(D);}
43764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  GlobalDecl(const FunctionDecl *D) { Init(D); }
44764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  GlobalDecl(const BlockDecl *D) { Init(D); }
45524387ae3dfc0c4cf2b095f83f9e47aa549b7e55Ben Langmuir  GlobalDecl(const CapturedDecl *D) { Init(D); }
46764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
48764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
49764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
50764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  : Value(D, Type) {}
51764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
52764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  : Value(D, Type) {}
53764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
54dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson  GlobalDecl getCanonicalDecl() const {
55dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson    GlobalDecl CanonGD;
56dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson    CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
57dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson    CanonGD.Value.setInt(Value.getInt());
58dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson
59dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson    return CanonGD;
60dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson  }
61dc5daec0d30959bf081544f72d378f6f96cf9b1aAnders Carlsson
62764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  const Decl *getDecl() const { return Value.getPointer(); }
63764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
64764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  CXXCtorType getCtorType() const {
65764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
66764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    return static_cast<CXXCtorType>(Value.getInt());
67764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  }
68764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
69764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  CXXDtorType getDtorType() const {
70764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
71764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    return static_cast<CXXDtorType>(Value.getInt());
72764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  }
73764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
74764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
75764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    return LHS.Value == RHS.Value;
76764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  }
77764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
78764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
79764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
80764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  static GlobalDecl getFromOpaquePtr(void *P) {
81764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    GlobalDecl GD;
82764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    GD.Value.setFromOpaqueValue(P);
83764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    return GD;
84764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  }
85a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor
86a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor  GlobalDecl getWithDecl(const Decl *D) {
87a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor    GlobalDecl Result(*this);
88a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor    Result.Value.setPointer(D);
89a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor    return Result;
90a29bf41b8f49578207ce36f6b21ff9bb7ee77babDouglas Gregor  }
91764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson};
92764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
93764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson} // end namespace clang
94764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
95764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlssonnamespace llvm {
96764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  template<class> struct DenseMapInfo;
97764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
98fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne  template<> struct DenseMapInfo<clang::GlobalDecl> {
99fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne    static inline clang::GlobalDecl getEmptyKey() {
100fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne      return clang::GlobalDecl();
101764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    }
102764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
103fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne    static inline clang::GlobalDecl getTombstoneKey() {
104fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne      return clang::GlobalDecl::
105764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson        getFromOpaquePtr(reinterpret_cast<void*>(-1));
106764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    }
107764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
108fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne    static unsigned getHashValue(clang::GlobalDecl GD) {
109764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson      return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
110764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    }
111764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
112fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne    static bool isEqual(clang::GlobalDecl LHS,
113fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne                        clang::GlobalDecl RHS) {
114764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson      return LHS == RHS;
115764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson    }
116764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
117764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson  };
118764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
11906159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner  // GlobalDecl isn't *technically* a POD type. However, its copy constructor,
12006159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner  // copy assignment operator, and destructor are all trivial.
12106159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner  template <>
122fd05ca03abdfb38f78b9535d996ecc9c39d3b0dbPeter Collingbourne  struct isPodLike<clang::GlobalDecl> {
12306159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner    static const bool value = true;
12406159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner  };
12506159e878569e5f39bf0e8f11b84ac3ad0970597Chris Lattner} // end namespace llvm
126764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson
127764d0c23724b3671dcbe20af152fa1ad45f45e15Anders Carlsson#endif
128