10b57cec5SDimitry Andric //===--- DeclAccessPair.h - A decl bundled with its path access -*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //  This file defines the DeclAccessPair class, which provides an
100b57cec5SDimitry Andric //  efficient representation of a pair of a NamedDecl* and an
110b57cec5SDimitry Andric //  AccessSpecifier.  Generally the access specifier gives the
120b57cec5SDimitry Andric //  natural access of a declaration when named in a class, as
130b57cec5SDimitry Andric //  defined in C++ [class.access.base]p1.
140b57cec5SDimitry Andric //
150b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #ifndef LLVM_CLANG_AST_DECLACCESSPAIR_H
180b57cec5SDimitry Andric #define LLVM_CLANG_AST_DECLACCESSPAIR_H
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric #include "clang/Basic/Specifiers.h"
210b57cec5SDimitry Andric #include "llvm/Support/DataTypes.h"
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric namespace clang {
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric class NamedDecl;
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric /// A POD class for pairing a NamedDecl* with an access specifier.
280b57cec5SDimitry Andric /// Can be put into unions.
290b57cec5SDimitry Andric class DeclAccessPair {
300b57cec5SDimitry Andric   uintptr_t Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric   enum { Mask = 0x3 };
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric public:
make(NamedDecl * D,AccessSpecifier AS)350b57cec5SDimitry Andric   static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
360b57cec5SDimitry Andric     DeclAccessPair p;
370b57cec5SDimitry Andric     p.set(D, AS);
380b57cec5SDimitry Andric     return p;
390b57cec5SDimitry Andric   }
400b57cec5SDimitry Andric 
getDecl()410b57cec5SDimitry Andric   NamedDecl *getDecl() const {
420b57cec5SDimitry Andric     return reinterpret_cast<NamedDecl*>(~Mask & Ptr);
430b57cec5SDimitry Andric   }
getAccess()440b57cec5SDimitry Andric   AccessSpecifier getAccess() const {
450b57cec5SDimitry Andric     return AccessSpecifier(Mask & Ptr);
460b57cec5SDimitry Andric   }
470b57cec5SDimitry Andric 
setDecl(NamedDecl * D)480b57cec5SDimitry Andric   void setDecl(NamedDecl *D) {
490b57cec5SDimitry Andric     set(D, getAccess());
500b57cec5SDimitry Andric   }
setAccess(AccessSpecifier AS)510b57cec5SDimitry Andric   void setAccess(AccessSpecifier AS) {
520b57cec5SDimitry Andric     set(getDecl(), AS);
530b57cec5SDimitry Andric   }
set(NamedDecl * D,AccessSpecifier AS)540b57cec5SDimitry Andric   void set(NamedDecl *D, AccessSpecifier AS) {
550b57cec5SDimitry Andric     Ptr = uintptr_t(AS) | reinterpret_cast<uintptr_t>(D);
560b57cec5SDimitry Andric   }
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric   operator NamedDecl*() const { return getDecl(); }
590b57cec5SDimitry Andric   NamedDecl *operator->() const { return getDecl(); }
600b57cec5SDimitry Andric };
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric #endif
64