1251876Speter//===--- DeclAccessPair.h - A decl bundled with its path access -*- C++ -*-===//
2251876Speter//
3253734Speter// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4251876Speter// See https://llvm.org/LICENSE.txt for license information.
5251876Speter// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6253734Speter//
7251876Speter//===----------------------------------------------------------------------===//
8251876Speter//
9251876Speter//  This file defines the DeclAccessPair class, which provides an
10251876Speter//  efficient representation of a pair of a NamedDecl* and an
11251876Speter//  AccessSpecifier.  Generally the access specifier gives the
12251876Speter//  natural access of a declaration when named in a class, as
13251876Speter//  defined in C++ [class.access.base]p1.
14251876Speter//
15251876Speter//===----------------------------------------------------------------------===//
16251876Speter
17251876Speter#ifndef LLVM_CLANG_AST_DECLACCESSPAIR_H
18251876Speter#define LLVM_CLANG_AST_DECLACCESSPAIR_H
19251876Speter
20251876Speter#include "clang/Basic/Specifiers.h"
21251876Speter#include "llvm/Support/DataTypes.h"
22251876Speter
23251876Speternamespace clang {
24251876Speter
25251876Speterclass NamedDecl;
26251876Speter
27251876Speter/// A POD class for pairing a NamedDecl* with an access specifier.
28251876Speter/// Can be put into unions.
29251876Speterclass DeclAccessPair {
30251876Speter  uintptr_t Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
31251876Speter
32251876Speter  enum { Mask = 0x3 };
33251876Speter
34251876Speterpublic:
35251876Speter  static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
36251876Speter    DeclAccessPair p;
37251876Speter    p.set(D, AS);
38251876Speter    return p;
39251876Speter  }
40251876Speter
41251876Speter  NamedDecl *getDecl() const {
42251876Speter    return reinterpret_cast<NamedDecl*>(~Mask & Ptr);
43251876Speter  }
44251876Speter  AccessSpecifier getAccess() const {
45251876Speter    return AccessSpecifier(Mask & Ptr);
46251876Speter  }
47251876Speter
48251876Speter  void setDecl(NamedDecl *D) {
49251876Speter    set(D, getAccess());
50251876Speter  }
51251876Speter  void setAccess(AccessSpecifier AS) {
52251876Speter    set(getDecl(), AS);
53251876Speter  }
54251876Speter  void set(NamedDecl *D, AccessSpecifier AS) {
55251876Speter    Ptr = uintptr_t(AS) | reinterpret_cast<uintptr_t>(D);
56251876Speter  }
57251876Speter
58251876Speter  operator NamedDecl*() const { return getDecl(); }
59251876Speter  NamedDecl *operator->() const { return getDecl(); }
60251876Speter};
61251876Speter}
62251876Speter
63251876Speter#endif
64251876Speter