1161755a09898c95d21bfff33707da9ca41cd53c5John McCall//===--- DeclAccessPair.h - A decl bundled with its path access -*- C++ -*-===//
2161755a09898c95d21bfff33707da9ca41cd53c5John McCall//
3161755a09898c95d21bfff33707da9ca41cd53c5John McCall//                     The LLVM Compiler Infrastructure
4161755a09898c95d21bfff33707da9ca41cd53c5John McCall//
5161755a09898c95d21bfff33707da9ca41cd53c5John McCall// This file is distributed under the University of Illinois Open Source
6161755a09898c95d21bfff33707da9ca41cd53c5John McCall// License. See LICENSE.TXT for details.
7161755a09898c95d21bfff33707da9ca41cd53c5John McCall//
8161755a09898c95d21bfff33707da9ca41cd53c5John McCall//===----------------------------------------------------------------------===//
9161755a09898c95d21bfff33707da9ca41cd53c5John McCall//
10161755a09898c95d21bfff33707da9ca41cd53c5John McCall//  This file defines the DeclAccessPair class, which provides an
11161755a09898c95d21bfff33707da9ca41cd53c5John McCall//  efficient representation of a pair of a NamedDecl* and an
12161755a09898c95d21bfff33707da9ca41cd53c5John McCall//  AccessSpecifier.  Generally the access specifier gives the
13161755a09898c95d21bfff33707da9ca41cd53c5John McCall//  natural access of a declaration when named in a class, as
14161755a09898c95d21bfff33707da9ca41cd53c5John McCall//  defined in C++ [class.access.base]p1.
15161755a09898c95d21bfff33707da9ca41cd53c5John McCall//
16161755a09898c95d21bfff33707da9ca41cd53c5John McCall//===----------------------------------------------------------------------===//
17161755a09898c95d21bfff33707da9ca41cd53c5John McCall
18161755a09898c95d21bfff33707da9ca41cd53c5John McCall#ifndef LLVM_CLANG_AST_DECLACCESSPAIR_H
19161755a09898c95d21bfff33707da9ca41cd53c5John McCall#define LLVM_CLANG_AST_DECLACCESSPAIR_H
20161755a09898c95d21bfff33707da9ca41cd53c5John McCall
21161755a09898c95d21bfff33707da9ca41cd53c5John McCall#include "clang/Basic/Specifiers.h"
222fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "llvm/Support/DataTypes.h"
23161755a09898c95d21bfff33707da9ca41cd53c5John McCall
24161755a09898c95d21bfff33707da9ca41cd53c5John McCallnamespace clang {
25161755a09898c95d21bfff33707da9ca41cd53c5John McCall
26161755a09898c95d21bfff33707da9ca41cd53c5John McCallclass NamedDecl;
27161755a09898c95d21bfff33707da9ca41cd53c5John McCall
28161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// A POD class for pairing a NamedDecl* with an access specifier.
29161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// Can be put into unions.
30161755a09898c95d21bfff33707da9ca41cd53c5John McCallclass DeclAccessPair {
3126c7dc32c7cc204b8255e4f5cbe48fbdb50ef5faRichard Smith  uintptr_t Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
32161755a09898c95d21bfff33707da9ca41cd53c5John McCall
33161755a09898c95d21bfff33707da9ca41cd53c5John McCall  enum { Mask = 0x3 };
34161755a09898c95d21bfff33707da9ca41cd53c5John McCall
35161755a09898c95d21bfff33707da9ca41cd53c5John McCallpublic:
36161755a09898c95d21bfff33707da9ca41cd53c5John McCall  static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
37161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DeclAccessPair p;
38161755a09898c95d21bfff33707da9ca41cd53c5John McCall    p.set(D, AS);
39161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return p;
40161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
41161755a09898c95d21bfff33707da9ca41cd53c5John McCall
42161755a09898c95d21bfff33707da9ca41cd53c5John McCall  NamedDecl *getDecl() const {
4326c7dc32c7cc204b8255e4f5cbe48fbdb50ef5faRichard Smith    return reinterpret_cast<NamedDecl*>(~Mask & Ptr);
44161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
45161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessSpecifier getAccess() const {
4626c7dc32c7cc204b8255e4f5cbe48fbdb50ef5faRichard Smith    return AccessSpecifier(Mask & Ptr);
47161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
48161755a09898c95d21bfff33707da9ca41cd53c5John McCall
49161755a09898c95d21bfff33707da9ca41cd53c5John McCall  void setDecl(NamedDecl *D) {
50161755a09898c95d21bfff33707da9ca41cd53c5John McCall    set(D, getAccess());
51161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
52161755a09898c95d21bfff33707da9ca41cd53c5John McCall  void setAccess(AccessSpecifier AS) {
53161755a09898c95d21bfff33707da9ca41cd53c5John McCall    set(getDecl(), AS);
54161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
55161755a09898c95d21bfff33707da9ca41cd53c5John McCall  void set(NamedDecl *D, AccessSpecifier AS) {
5626c7dc32c7cc204b8255e4f5cbe48fbdb50ef5faRichard Smith    Ptr = uintptr_t(AS) | reinterpret_cast<uintptr_t>(D);
57161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
58161755a09898c95d21bfff33707da9ca41cd53c5John McCall
59161755a09898c95d21bfff33707da9ca41cd53c5John McCall  operator NamedDecl*() const { return getDecl(); }
60161755a09898c95d21bfff33707da9ca41cd53c5John McCall  NamedDecl *operator->() const { return getDecl(); }
61161755a09898c95d21bfff33707da9ca41cd53c5John McCall};
62161755a09898c95d21bfff33707da9ca41cd53c5John McCall}
63161755a09898c95d21bfff33707da9ca41cd53c5John McCall
64161755a09898c95d21bfff33707da9ca41cd53c5John McCall// Take a moment to tell SmallVector that DeclAccessPair is POD.
65161755a09898c95d21bfff33707da9ca41cd53c5John McCallnamespace llvm {
66161755a09898c95d21bfff33707da9ca41cd53c5John McCalltemplate<typename> struct isPodLike;
67161755a09898c95d21bfff33707da9ca41cd53c5John McCalltemplate<> struct isPodLike<clang::DeclAccessPair> {
68161755a09898c95d21bfff33707da9ca41cd53c5John McCall   static const bool value = true;
69161755a09898c95d21bfff33707da9ca41cd53c5John McCall};
70161755a09898c95d21bfff33707da9ca41cd53c5John McCall}
71161755a09898c95d21bfff33707da9ca41cd53c5John McCall
72161755a09898c95d21bfff33707da9ca41cd53c5John McCall#endif
73