Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:31

0001 //===--- DeclAccessPair.h - A decl bundled with its path access -*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  This file defines the DeclAccessPair class, which provides an
0010 //  efficient representation of a pair of a NamedDecl* and an
0011 //  AccessSpecifier.  Generally the access specifier gives the
0012 //  natural access of a declaration when named in a class, as
0013 //  defined in C++ [class.access.base]p1.
0014 //
0015 //===----------------------------------------------------------------------===//
0016 
0017 #ifndef LLVM_CLANG_AST_DECLACCESSPAIR_H
0018 #define LLVM_CLANG_AST_DECLACCESSPAIR_H
0019 
0020 #include "clang/Basic/Specifiers.h"
0021 #include "llvm/Support/DataTypes.h"
0022 #include "llvm/Support/Endian.h"
0023 
0024 namespace clang {
0025 
0026 class NamedDecl;
0027 
0028 /// A POD class for pairing a NamedDecl* with an access specifier.
0029 /// Can be put into unions.
0030 class DeclAccessPair {
0031   /// Use the lower 2 bit to store AccessSpecifier. Use the higher
0032   /// 61 bit to store the pointer to a NamedDecl or the DeclID to
0033   /// a NamedDecl. If the 3rd bit is set, storing the DeclID, otherwise
0034   /// storing the pointer.
0035   llvm::support::detail::packed_endian_specific_integral<
0036       uint64_t, llvm::endianness::native, alignof(void *)>
0037       Ptr;
0038 
0039   enum { ASMask = 0x3, Mask = 0x7 };
0040 
0041   bool isDeclID() const { return (Ptr >> 2) & 0x1; }
0042 
0043 public:
0044   static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
0045     DeclAccessPair p;
0046     p.set(D, AS);
0047     return p;
0048   }
0049 
0050   static DeclAccessPair makeLazy(uint64_t ID, AccessSpecifier AS) {
0051     DeclAccessPair p;
0052     p.Ptr = (ID << 3) | (0x1 << 2) | uint64_t(AS);
0053     return p;
0054   }
0055 
0056   uint64_t getDeclID() const {
0057     assert(isDeclID());
0058     return (~Mask & Ptr) >> 3;
0059   }
0060 
0061   NamedDecl *getDecl() const {
0062     assert(!isDeclID());
0063     return reinterpret_cast<NamedDecl*>(~Mask & Ptr);
0064   }
0065   AccessSpecifier getAccess() const { return AccessSpecifier(ASMask & Ptr); }
0066 
0067   void setDecl(NamedDecl *D) {
0068     set(D, getAccess());
0069   }
0070   void setAccess(AccessSpecifier AS) {
0071     set(getDecl(), AS);
0072   }
0073   void set(NamedDecl *D, AccessSpecifier AS) {
0074     Ptr = uint64_t(AS) | reinterpret_cast<uint64_t>(D);
0075   }
0076 
0077   operator NamedDecl*() const { return getDecl(); }
0078   NamedDecl *operator->() const { return getDecl(); }
0079 };
0080 
0081 // Make sure DeclAccessPair is pointer-aligned types.
0082 static_assert(alignof(DeclAccessPair) == alignof(void *));
0083 // Make sure DeclAccessPair is still POD.
0084 static_assert(std::is_standard_layout_v<DeclAccessPair> &&
0085               std::is_trivial_v<DeclAccessPair>);
0086 }
0087 
0088 #endif