Lines Matching +full:block +full:- +full:offset

1 //===--- Pointer.h - Types for the constexpr VM -----------------*- C++ -*-===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
11 //===----------------------------------------------------------------------===//
26 class Block;
37 /// The block the pointer is pointing to.
38 Block *Pointee;
48 enum class Storage { Block, Int };
50 /// A pointer to a memory block, live or dead.
53 /// a live block, it is a link in the chain of pointers pointing to the block.
55 /// In the simplest form, a Pointer has a Block* (the pointee) and both Base
56 /// and Offset are 0, which means it will point to raw data.
63 /// The Offset field is used to access the actual data. In other words, the
65 /// Pointee->rawData() + Pointer.Offset.
68 /// Pointee Offset
73 /// │ Block │ InlineDesc │ InitMap │ Actual Data │
90 Pointer(Block *B);
91 Pointer(Block *B, uint64_t BaseAndOffset);
94 Pointer(uint64_t Address, const Descriptor *Desc, uint64_t Offset = 0)
95 : Offset(Offset), StorageKind(Storage::Int) {
110 Offset == P.Offset;
115 Offset == P.Offset;
128 return asIntPointer().Value + (Offset * elemSize());
129 return reinterpret_cast<uint64_t>(asBlockPointer().Pointee) + Offset;
143 getDeclDesc()->getSize());
145 if (getFieldDesc()->ElemDesc)
155 unsigned Field = Offset + Off;
161 /// Subtract the given offset from the current Base and Offset
164 assert(Offset >= Off);
165 unsigned O = Offset - Off;
178 // Pointer to an array of base types - enter block.
181 Offset == 0 ? Offset : PastEndMark);
183 // Pointer is one past end - magic offset marks that.
189 // descriptors. If Offset != Base, then the pointer already points to
193 if (Offset != asBlockPointer().Base)
196 Offset + sizeof(InitMapPtr));
199 // Pointer is to a field or array element - enter it.
200 if (Offset != asBlockPointer().Base)
201 return Pointer(asBlockPointer().Pointee, Offset, Offset);
204 if (!getFieldDesc()->isArray())
214 Block *Pointee = asBlockPointer().Pointee;
217 // Revert to an outer one-past-end pointer.
228 if (asBlockPointer().Base != Offset)
236 unsigned Next = asBlockPointer().Base - getInlineDesc()->Offset;
238 (Next == Pointee->getDescriptor()->getMetadataSize())
240 : getDescriptor(Next)->Desc;
241 if (!Desc->IsArray)
243 return Pointer(Pointee, Next, Offset);
251 return asIntPointer().Value == 0 && Offset == 0;
257 return asBlockPointer().Pointee && !asBlockPointer().Pointee->IsDead;
264 return !isRoot() && getFieldDesc()->asDecl();
274 return asBlockPointer().Pointee->Desc;
276 SourceLocation getDeclLoc() const { return getDeclDesc()->getLocation(); }
281 return getDeclDesc()->getSource();
284 return asIntPointer().Desc ? asIntPointer().Desc->getSource() : DeclTy();
290 assert(Offset == PastEndMark && "cannot get base of a block");
293 unsigned NewBase = asBlockPointer().Base - getInlineDesc()->Offset;
299 assert(Offset != 0 && Offset != PastEndMark && "not an array element");
302 assert(Offset != asBlockPointer().Base && "not an array element");
314 return getInlineDesc()->Desc;
319 if (inPrimitiveArray() && Offset != asBlockPointer().Base) {
322 if (const auto *AT = getFieldDesc()->getType()->getAsArrayTypeUnsafe())
323 return AT->getElementType();
324 if (const auto *CT = getFieldDesc()->getType()->getAs<ComplexType>())
325 return CT->getElementType();
326 if (const auto *CT = getFieldDesc()->getType()->getAs<VectorType>())
327 return CT->getElementType();
329 return getFieldDesc()->getType();
341 return asIntPointer().Desc->getElemSize();
345 return getDeclDesc()->getSize();
346 return getFieldDesc()->getElemSize();
351 return getFieldDesc()->getSize();
354 /// Returns the offset into an array.
356 assert(Offset != PastEndMark && "invalid offset");
358 return Offset;
361 if (Offset != asBlockPointer().Base) {
362 if (getFieldDesc()->ElemDesc)
367 return Offset - asBlockPointer().Base - Adjust;
373 return inArray() && Offset == asBlockPointer().Base;
379 return getFieldDesc()->IsArray;
385 return getFieldDesc()->isPrimitiveArray();
392 return getFieldDesc()->isUnknownSizeArray();
397 return inArray() && asBlockPointer().Base != Offset;
400 /// Pointer points directly to a block.
405 asBlockPointer().Pointee->getDescriptor()->getMetadataSize() ||
424 bool isBlockPointer() const { return StorageKind == Storage::Block; }
428 const Record *getRecord() const { return getFieldDesc()->ElemRecord; }
429 /// Returns the element record type, if this is a non-primive array.
431 const Descriptor *ElemDesc = getFieldDesc()->ElemDesc;
432 return ElemDesc ? ElemDesc->ElemRecord : nullptr;
435 const FieldDecl *getField() const { return getFieldDesc()->asFieldDecl(); }
443 return asBlockPointer().Pointee && asBlockPointer().Pointee->isExtern();
451 return asBlockPointer().Pointee->isStatic();
457 return asBlockPointer().Pointee->isTemporary();
468 return !isRoot() && getInlineDesc()->IsFieldMutable;
476 if (const ValueDecl *VD = getDeclDesc()->asValueDecl())
477 return VD->isWeak();
486 return isRoot() || getInlineDesc()->IsActive;
489 bool isBaseClass() const { return isField() && getInlineDesc()->IsBase; }
491 return isField() && getInlineDesc()->IsVirtualBase;
501 return getDeclDesc()->isDummy();
508 return isRoot() ? getDeclDesc()->IsConst : getInlineDesc()->IsConst;
515 return asBlockPointer().Pointee->getDeclID();
520 /// Returns the byte offset from the start.
523 return asIntPointer().Value + Offset;
526 return Offset;
536 const Block *block() const { return asBlockPointer().Pointee; }
548 asBlockPointer().Base == Offset)
576 return !isZero() && Offset > PointeeStorage.BS.Pointee->getSize();
579 /// Checks if the pointer is an out-of-bounds element pointer.
580 bool isElementPastEnd() const { return Offset == PastEndMark; }
582 /// Checks if the pointer is pointing to a zero-size array.
583 bool isZeroSizeArray() const { return getFieldDesc()->isZeroSizeArray(); }
591 assert(Offset + sizeof(T) <=
592 asBlockPointer().Pointee->getDescriptor()->getAllocSize());
595 return *reinterpret_cast<T *>(asBlockPointer().Pointee->rawData() +
598 return *reinterpret_cast<T *>(asBlockPointer().Pointee->rawData() + Offset);
606 return reinterpret_cast<T *>(asBlockPointer().Pointee->data() +
610 /// Whether this block can be read from at all. This is only true for
611 /// block pointers that point to a valid location inside that block.
633 if (Offset < Other.Offset)
635 else if (Offset > Other.Offset)
650 friend class Block;
657 Pointer(Block *Pointee, unsigned Base, uint64_t Offset);
662 assert(asBlockPointer().Base <= asBlockPointer().Pointee->getSize());
666 /// Returns a descriptor at a given offset.
667 InlineDescriptor *getDescriptor(unsigned Offset) const {
668 assert(Offset != 0 && "Not a nested pointer");
672 asBlockPointer().Pointee->rawData() + Offset) -
680 return *reinterpret_cast<InitMapPtr *>(asBlockPointer().Pointee->rawData() +
684 /// Offset into the storage.
685 uint64_t Offset = 0;