1207619Srdivacky//===--- DeclAccessPair.h - A decl bundled with its path access -*- C++ -*-===//
2207619Srdivacky//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6207619Srdivacky//
7207619Srdivacky//===----------------------------------------------------------------------===//
8207619Srdivacky//
9207619Srdivacky//  This file defines the DeclAccessPair class, which provides an
10207619Srdivacky//  efficient representation of a pair of a NamedDecl* and an
11207619Srdivacky//  AccessSpecifier.  Generally the access specifier gives the
12207619Srdivacky//  natural access of a declaration when named in a class, as
13207619Srdivacky//  defined in C++ [class.access.base]p1.
14207619Srdivacky//
15207619Srdivacky//===----------------------------------------------------------------------===//
16207619Srdivacky
17207619Srdivacky#ifndef LLVM_CLANG_AST_DECLACCESSPAIR_H
18207619Srdivacky#define LLVM_CLANG_AST_DECLACCESSPAIR_H
19207619Srdivacky
20207619Srdivacky#include "clang/Basic/Specifiers.h"
21249423Sdim#include "llvm/Support/DataTypes.h"
22207619Srdivacky
23207619Srdivackynamespace clang {
24207619Srdivacky
25207619Srdivackyclass NamedDecl;
26207619Srdivacky
27207619Srdivacky/// A POD class for pairing a NamedDecl* with an access specifier.
28207619Srdivacky/// Can be put into unions.
29207619Srdivackyclass DeclAccessPair {
30261991Sdim  uintptr_t Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
31207619Srdivacky
32207619Srdivacky  enum { Mask = 0x3 };
33207619Srdivacky
34207619Srdivackypublic:
35207619Srdivacky  static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
36207619Srdivacky    DeclAccessPair p;
37207619Srdivacky    p.set(D, AS);
38207619Srdivacky    return p;
39207619Srdivacky  }
40207619Srdivacky
41207619Srdivacky  NamedDecl *getDecl() const {
42261991Sdim    return reinterpret_cast<NamedDecl*>(~Mask & Ptr);
43207619Srdivacky  }
44207619Srdivacky  AccessSpecifier getAccess() const {
45261991Sdim    return AccessSpecifier(Mask & Ptr);
46207619Srdivacky  }
47207619Srdivacky
48207619Srdivacky  void setDecl(NamedDecl *D) {
49207619Srdivacky    set(D, getAccess());
50207619Srdivacky  }
51207619Srdivacky  void setAccess(AccessSpecifier AS) {
52207619Srdivacky    set(getDecl(), AS);
53207619Srdivacky  }
54207619Srdivacky  void set(NamedDecl *D, AccessSpecifier AS) {
55261991Sdim    Ptr = uintptr_t(AS) | reinterpret_cast<uintptr_t>(D);
56207619Srdivacky  }
57207619Srdivacky
58207619Srdivacky  operator NamedDecl*() const { return getDecl(); }
59207619Srdivacky  NamedDecl *operator->() const { return getDecl(); }
60207619Srdivacky};
61207619Srdivacky}
62207619Srdivacky
63207619Srdivacky#endif
64