================ @@ -326,25 +326,25 @@ struct LazyOffsetPtr { /// /// 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; + mutable uintptr_t Ptr = 0; public: LazyOffsetPtr() = default; - explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) {} + explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uintptr_t>(Ptr)) {} - explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) { - assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); + explicit LazyOffsetPtr(uintptr_t Offset) : Ptr((Offset << 1) | 0x01) { + assert((Offset << 1 >> 1) == Offset && "Offsets must fit in addressable bits"); if (Offset == 0) Ptr = 0; } LazyOffsetPtr &operator=(T *Ptr) { - this->Ptr = reinterpret_cast<uint64_t>(Ptr); + this->Ptr = reinterpret_cast<uintptr_t>(Ptr); return *this; } - LazyOffsetPtr &operator=(uint64_t Offset) { - assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); + LazyOffsetPtr &operator=(uintptr_t Offset) { ---------------- jrtc27 wrote:
If not, you probably need something like: ```diff diff --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h index 385c32edbae0..3f0c63d56d67 100644 --- a/clang/include/clang/AST/ExternalASTSource.h +++ b/clang/include/clang/AST/ExternalASTSource.h @@ -25,6 +25,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/iterator.h" #include "llvm/Support/PointerLikeTypeTraits.h" +#include <algorithm> #include <cassert> #include <cstddef> #include <cstdint> @@ -326,29 +327,43 @@ struct LazyOffsetPtr { /// /// 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; + static constexpr size_t DataSize = std::max(sizeof(uint64_t), sizeof(T *)); + alignas(uint64_t) alignas(T *) mutable char Data[DataSize] = {}; + + template <typename U> U &As() const { + if (llvm::sys::IsBigEndianHost) + return *reinterpret_cast<U *>(Data + DataSize - sizeof(U)); + else + return *reinterpret_cast<U *>(Data); + } + + char &AsLSB() const { return As<char>(); } + T *&AsPtr() const { return As<T *>(); } + uint64_t &AsU64() const { return As<uint64_t>(); } public: LazyOffsetPtr() = default; - explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) {} + explicit LazyOffsetPtr(T *Ptr) : Data() { AsPtr() = Ptr; } - explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) { + explicit LazyOffsetPtr(uint64_t Offset) : Data() { assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); if (Offset == 0) - Ptr = 0; + AsPtr() = NULL; + else + AsU64() = (Offset << 1) | 0x01; } LazyOffsetPtr &operator=(T *Ptr) { - this->Ptr = reinterpret_cast<uint64_t>(Ptr); + AsPtr() = Ptr; return *this; } LazyOffsetPtr &operator=(uint64_t Offset) { assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); if (Offset == 0) - Ptr = 0; + AsPtr() = NULL; else - Ptr = (Offset << 1) | 0x01; + AsU64() = (Offset << 1) | 0x01; return *this; } @@ -356,15 +371,15 @@ public: /// Whether this pointer is non-NULL. /// /// This operation does not require the AST node to be deserialized. - explicit operator bool() const { return Ptr != 0; } + explicit operator bool() const { return isOffset() || AsPtr() != NULL; } /// Whether this pointer is non-NULL. /// /// This operation does not require the AST node to be deserialized. - bool isValid() const { return Ptr != 0; } + bool isValid() const { return isOffset() || AsPtr() != NULL; } /// Whether this pointer is currently stored as an offset. - bool isOffset() const { return Ptr & 0x01; } + bool isOffset() const { return AsLSB() & 0x01; } /// Retrieve the pointer to the AST node that this lazy pointer points to. /// @@ -375,9 +390,9 @@ public: if (isOffset()) { assert(Source && "Cannot deserialize a lazy pointer without an AST source"); - Ptr = reinterpret_cast<uint64_t>((Source->*Get)(OffsT(Ptr >> 1))); + AsPtr() = (Source->*Get)(OffsT(AsU64() >> 1)); } - return reinterpret_cast<T*>(Ptr); + return AsPtr(); } /// Retrieve the address of the AST node pointer. Deserializes the pointee if @@ -385,7 +400,7 @@ public: T **getAddressOfPointer(ExternalASTSource *Source) const { // Ensure the integer is in pointer form. (void)get(Source); - return reinterpret_cast<T**>(&Ptr); + return &AsPtr(); } }; ``` https://github.com/llvm/llvm-project/pull/111995 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits