1207619Srdivacky//===--- DeclAccessPair.h - A decl bundled with its path access -*- C++ -*-===//
2207619Srdivacky//
3207619Srdivacky//                     The LLVM Compiler Infrastructure
4207619Srdivacky//
5207619Srdivacky// This file is distributed under the University of Illinois Open Source
6207619Srdivacky// License. See LICENSE.TXT for details.
7207619Srdivacky//
8207619Srdivacky//===----------------------------------------------------------------------===//
9207619Srdivacky//
10207619Srdivacky//  This file defines the DeclAccessPair class, which provides an
11207619Srdivacky//  efficient representation of a pair of a NamedDecl* and an
12207619Srdivacky//  AccessSpecifier.  Generally the access specifier gives the
13207619Srdivacky//  natural access of a declaration when named in a class, as
14207619Srdivacky//  defined in C++ [class.access.base]p1.
15207619Srdivacky//
16207619Srdivacky//===----------------------------------------------------------------------===//
17207619Srdivacky
18207619Srdivacky#ifndef LLVM_CLANG_AST_DECLACCESSPAIR_H
19207619Srdivacky#define LLVM_CLANG_AST_DECLACCESSPAIR_H
20207619Srdivacky
21207619Srdivacky#include "clang/Basic/Specifiers.h"
22252723Sdim#include "llvm/Support/DataTypes.h"
23207619Srdivacky
24207619Srdivackynamespace clang {
25207619Srdivacky
26207619Srdivackyclass NamedDecl;
27207619Srdivacky
28207619Srdivacky/// A POD class for pairing a NamedDecl* with an access specifier.
29207619Srdivacky/// Can be put into unions.
30207619Srdivackyclass DeclAccessPair {
31263509Sdim  uintptr_t Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
32207619Srdivacky
33207619Srdivacky  enum { Mask = 0x3 };
34207619Srdivacky
35207619Srdivackypublic:
36207619Srdivacky  static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
37207619Srdivacky    DeclAccessPair p;
38207619Srdivacky    p.set(D, AS);
39207619Srdivacky    return p;
40207619Srdivacky  }
41207619Srdivacky
42207619Srdivacky  NamedDecl *getDecl() const {
43263509Sdim    return reinterpret_cast<NamedDecl*>(~Mask & Ptr);
44207619Srdivacky  }
45207619Srdivacky  AccessSpecifier getAccess() const {
46263509Sdim    return AccessSpecifier(Mask & Ptr);
47207619Srdivacky  }
48207619Srdivacky
49207619Srdivacky  void setDecl(NamedDecl *D) {
50207619Srdivacky    set(D, getAccess());
51207619Srdivacky  }
52207619Srdivacky  void setAccess(AccessSpecifier AS) {
53207619Srdivacky    set(getDecl(), AS);
54207619Srdivacky  }
55207619Srdivacky  void set(NamedDecl *D, AccessSpecifier AS) {
56263509Sdim    Ptr = uintptr_t(AS) | reinterpret_cast<uintptr_t>(D);
57207619Srdivacky  }
58207619Srdivacky
59207619Srdivacky  operator NamedDecl*() const { return getDecl(); }
60207619Srdivacky  NamedDecl *operator->() const { return getDecl(); }
61207619Srdivacky};
62207619Srdivacky}
63207619Srdivacky
64207619Srdivacky// Take a moment to tell SmallVector that DeclAccessPair is POD.
65207619Srdivackynamespace llvm {
66207619Srdivackytemplate<typename> struct isPodLike;
67207619Srdivackytemplate<> struct isPodLike<clang::DeclAccessPair> {
68207619Srdivacky   static const bool value = true;
69207619Srdivacky};
70207619Srdivacky}
71207619Srdivacky
72207619Srdivacky#endif
73