================ @@ -321,50 +322,87 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> { /// external AST source itself. template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT Offset)> struct LazyOffsetPtr { - /// Either a pointer to an AST node or the offset within the - /// external AST source where the AST node can be found. - /// - /// If the low bit is clear, a pointer to the AST node. If the low - /// bit is set, the upper 63 bits are the offset. - mutable uint64_t Ptr = 0; + /// Storage for a pointer or an offset, for the case where pointers are 64 + /// bits wide. The least-significant bit is used as the discriminator. If the + /// bit is clear, a pointer to the AST node. If the bit is set, the upper 63 + /// bits are the offset. + union StorageType64 { + StorageType64(uint64_t Offset) : ShiftedOffset((Offset << 1) | 1) { + assert(isOffset()); + } + StorageType64(T *Ptr) : Pointer(Ptr) { assert(!isOffset()); } + + bool isOffset() { return llvm::bit_cast<uint64_t>(*this) & 1; } + uint64_t offset() { return ShiftedOffset >> 1; } + T *&pointer() { return Pointer; } + + uint64_t ShiftedOffset; + T *Pointer; + }; + + /// Storage for a pointer or an offset, for the case where pointers are not 64 + /// bits wide. + union StorageType32 { + StorageType32(uint64_t Off) : Offset{true, Off} {} + StorageType32(T *Ptr) : Pointer{false, Ptr} {} + + bool isOffset() { return Offset.IsOffset; } + uint64_t offset() { return Offset.Offset; } + T *&pointer() { return Pointer.Pointer; } + + struct OffsetType { + uint64_t IsOffset : 1; + uint64_t Offset : 63; + } Offset; + struct PointerType { + uint64_t IsOffset : 1; + T *Pointer; + } Pointer; + }; + + mutable std::conditional_t<sizeof(uint64_t) == sizeof(T *), StorageType64, + StorageType32> ---------------- zygoloid wrote:
That's true. How much should we worry about that? Such systems aren't going to be efficient in general due to the large numbers of pointers in the AST. https://github.com/llvm/llvm-project/pull/112806 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits