[clang] [clang] Make LazyOffsetPtr more portable (PR #112927)
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 18 09:43:27 PDT 2024
================
@@ -326,45 +328,65 @@ 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 unsigned char Data[DataSize] = {};
+
+ unsigned char GetLSB() const {
+ return Data[llvm::sys::IsBigEndianHost ? DataSize - 1 : 0];
+ }
+
+ template <typename U> U &As(bool New) const {
+ unsigned char *Obj =
+ Data + (llvm::sys::IsBigEndianHost ? DataSize - sizeof(U) : 0);
+ if (New)
+ return *new (Obj) U;
+ return *std::launder(reinterpret_cast<U *>(Obj));
+ }
+
+ T *&GetPtr() const { return As<T *>(false); }
+ uint64_t &GetU64() const { return As<uint64_t>(false); }
+ void SetPtr(T *Ptr) const { As<T *>(true) = Ptr; }
+ void SetU64(uint64_t U64) const { As<uint64_t>(true) = U64; }
public:
LazyOffsetPtr() = default;
- explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) {}
+ explicit LazyOffsetPtr(T *Ptr) : Data() { SetPtr(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;
+ SetPtr(NULL);
----------------
zygoloid wrote:
Please use `nullptr` here and below
https://github.com/llvm/llvm-project/pull/112927
More information about the cfe-commits
mailing list