1178476Sjb//===--- DeclAccessPair.h - A decl bundled with its path access -*- C++ -*-===//
2178476Sjb//
3178476Sjb//                     The LLVM Compiler Infrastructure
4178476Sjb//
5178476Sjb// This file is distributed under the University of Illinois Open Source
6178476Sjb// License. See LICENSE.TXT for details.
7178476Sjb//
8178476Sjb//===----------------------------------------------------------------------===//
9178476Sjb//
10178476Sjb//  This file defines the DeclAccessPair class, which provides an
11178476Sjb//  efficient representation of a pair of a NamedDecl* and an
12178476Sjb//  AccessSpecifier.  Generally the access specifier gives the
13178476Sjb//  natural access of a declaration when named in a class, as
14178476Sjb//  defined in C++ [class.access.base]p1.
15178476Sjb//
16178476Sjb//===----------------------------------------------------------------------===//
17178476Sjb
18178476Sjb#ifndef LLVM_CLANG_AST_DECLACCESSPAIR_H
19178476Sjb#define LLVM_CLANG_AST_DECLACCESSPAIR_H
20178476Sjb
21178476Sjb#include "clang/Basic/Specifiers.h"
22178476Sjb#include "llvm/Support/DataTypes.h"
23178476Sjb
24178476Sjbnamespace clang {
25178476Sjb
26178476Sjbclass NamedDecl;
27178476Sjb
28178476Sjb/// A POD class for pairing a NamedDecl* with an access specifier.
29178476Sjb/// Can be put into unions.
30178476Sjbclass DeclAccessPair {
31178476Sjb  uintptr_t Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
32178476Sjb
33178476Sjb  enum { Mask = 0x3 };
34178476Sjb
35178476Sjbpublic:
36178476Sjb  static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
37178476Sjb    DeclAccessPair p;
38178476Sjb    p.set(D, AS);
39178476Sjb    return p;
40178476Sjb  }
41178476Sjb
42178476Sjb  NamedDecl *getDecl() const {
43178476Sjb    return reinterpret_cast<NamedDecl*>(~Mask & Ptr);
44178476Sjb  }
45178476Sjb  AccessSpecifier getAccess() const {
46178476Sjb    return AccessSpecifier(Mask & Ptr);
47178476Sjb  }
48178476Sjb
49178476Sjb  void setDecl(NamedDecl *D) {
50178476Sjb    set(D, getAccess());
51178476Sjb  }
52178476Sjb  void setAccess(AccessSpecifier AS) {
53178476Sjb    set(getDecl(), AS);
54178476Sjb  }
55  void set(NamedDecl *D, AccessSpecifier AS) {
56    Ptr = uintptr_t(AS) | reinterpret_cast<uintptr_t>(D);
57  }
58
59  operator NamedDecl*() const { return getDecl(); }
60  NamedDecl *operator->() const { return getDecl(); }
61};
62}
63
64// Take a moment to tell SmallVector that DeclAccessPair is POD.
65namespace llvm {
66template<typename> struct isPodLike;
67template<> struct isPodLike<clang::DeclAccessPair> {
68   static const bool value = true;
69};
70}
71
72#endif
73