diff options
Diffstat (limited to 'clang/lib/AST/Interp/Pointer.h')
-rw-r--r-- | clang/lib/AST/Interp/Pointer.h | 353 |
1 files changed, 0 insertions, 353 deletions
diff --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h deleted file mode 100644 index b8fa98e24fa..00000000000 --- a/clang/lib/AST/Interp/Pointer.h +++ /dev/null @@ -1,353 +0,0 @@ -//===--- Pointer.h - Types for the constexpr VM -----------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Defines the classes responsible for pointer tracking. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_AST_INTERP_POINTER_H -#define LLVM_CLANG_AST_INTERP_POINTER_H - -#include "Block.h" -#include "Descriptor.h" -#include "clang/AST/Decl.h" -#include "clang/AST/DeclCXX.h" -#include "clang/AST/Expr.h" -#include "clang/AST/ComparisonCategories.h" -#include "llvm/ADT/PointerUnion.h" -#include "llvm/Support/raw_ostream.h" - -namespace clang { -namespace interp { -class Block; -class DeadBlock; -class Context; -class InterpState; -class Pointer; -class Function; -enum PrimType : unsigned; - -/// A pointer to a memory block, live or dead. -/// -/// This object can be allocated into interpreter stack frames. If pointing to -/// a live block, it is a link in the chain of pointers pointing to the block. -class Pointer { -private: - static constexpr unsigned PastEndMark = (unsigned)-1; - static constexpr unsigned RootPtrMark = (unsigned)-1; - -public: - Pointer() {} - Pointer(Block *B); - Pointer(const Pointer &P); - Pointer(Pointer &&P); - ~Pointer(); - - void operator=(const Pointer &P); - void operator=(Pointer &&P); - - /// Converts the pointer to an APValue. - APValue toAPValue() const; - - /// Offsets a pointer inside an array. - Pointer atIndex(unsigned Idx) const { - if (Base == RootPtrMark) - return Pointer(Pointee, RootPtrMark, getDeclDesc()->getSize()); - unsigned Off = Idx * elemSize(); - if (getFieldDesc()->ElemDesc) - Off += sizeof(InlineDescriptor); - else - Off += sizeof(InitMap *); - return Pointer(Pointee, Base, Base + Off); - } - - /// Creates a pointer to a field. - Pointer atField(unsigned Off) const { - unsigned Field = Offset + Off; - return Pointer(Pointee, Field, Field); - } - - /// Restricts the scope of an array element pointer. - Pointer narrow() const { - // Null pointers cannot be narrowed. - if (isZero() || isUnknownSizeArray()) - return *this; - - // Pointer to an array of base types - enter block. - if (Base == RootPtrMark) - return Pointer(Pointee, 0, Offset == 0 ? Offset : PastEndMark); - - // Pointer is one past end - magic offset marks that. - if (isOnePastEnd()) - return Pointer(Pointee, Base, PastEndMark); - - // Primitive arrays are a bit special since they do not have inline - // descriptors. If Offset != Base, then the pointer already points to - // an element and there is nothing to do. Otherwise, the pointer is - // adjusted to the first element of the array. - if (inPrimitiveArray()) { - if (Offset != Base) - return *this; - return Pointer(Pointee, Base, Offset + sizeof(InitMap *)); - } - - // Pointer is to a field or array element - enter it. - if (Offset != Base) - return Pointer(Pointee, Offset, Offset); - - // Enter the first element of an array. - if (!getFieldDesc()->isArray()) - return *this; - - const unsigned NewBase = Base + sizeof(InlineDescriptor); - return Pointer(Pointee, NewBase, NewBase); - } - - /// Expands a pointer to the containing array, undoing narrowing. - Pointer expand() const { - if (isElementPastEnd()) { - // Revert to an outer one-past-end pointer. - unsigned Adjust; - if (inPrimitiveArray()) - Adjust = sizeof(InitMap *); - else - Adjust = sizeof(InlineDescriptor); - return Pointer(Pointee, Base, Base + getSize() + Adjust); - } - - // Do not step out of array elements. - if (Base != Offset) - return *this; - - // If at base, point to an array of base types. - if (Base == 0) - return Pointer(Pointee, RootPtrMark, 0); - - // Step into the containing array, if inside one. - unsigned Next = Base - getInlineDesc()->Offset; - Descriptor *Desc = Next == 0 ? getDeclDesc() : getDescriptor(Next)->Desc; - if (!Desc->IsArray) - return *this; - return Pointer(Pointee, Next, Offset); - } - - /// Checks if the pointer is null. - bool isZero() const { return Pointee == nullptr; } - /// Checks if the pointer is live. - bool isLive() const { return Pointee && !Pointee->IsDead; } - /// Checks if the item is a field in an object. - bool isField() const { return Base != 0 && Base != RootPtrMark; } - - /// Accessor for information about the declaration site. - Descriptor *getDeclDesc() const { return Pointee->Desc; } - SourceLocation getDeclLoc() const { return getDeclDesc()->getLocation(); } - - /// Returns a pointer to the object of which this pointer is a field. - Pointer getBase() const { - if (Base == RootPtrMark) { - assert(Offset == PastEndMark && "cannot get base of a block"); - return Pointer(Pointee, Base, 0); - } - assert(Offset == Base && "not an inner field"); - unsigned NewBase = Base - getInlineDesc()->Offset; - return Pointer(Pointee, NewBase, NewBase); - } - /// Returns the parent array. - Pointer getArray() const { - if (Base == RootPtrMark) { - assert(Offset != 0 && Offset != PastEndMark && "not an array element"); - return Pointer(Pointee, Base, 0); - } - assert(Offset != Base && "not an array element"); - return Pointer(Pointee, Base, Base); - } - - /// Accessors for information about the innermost field. - Descriptor *getFieldDesc() const { - if (Base == 0 || Base == RootPtrMark) - return getDeclDesc(); - return getInlineDesc()->Desc; - } - - /// Returns the type of the innermost field. - QualType getType() const { return getFieldDesc()->getType(); } - - /// Returns the element size of the innermost field. - size_t elemSize() const { - if (Base == RootPtrMark) - return getDeclDesc()->getSize(); - return getFieldDesc()->getElemSize(); - } - /// Returns the total size of the innermost field. - size_t getSize() const { return getFieldDesc()->getSize(); } - - /// Returns the offset into an array. - unsigned getOffset() const { - assert(Offset != PastEndMark && "invalid offset"); - if (Base == RootPtrMark) - return Offset; - - unsigned Adjust = 0; - if (Offset != Base) { - if (getFieldDesc()->ElemDesc) - Adjust = sizeof(InlineDescriptor); - else - Adjust = sizeof(InitMap *); - } - return Offset - Base - Adjust; - } - - /// Checks if the innermost field is an array. - bool inArray() const { return getFieldDesc()->IsArray; } - /// Checks if the structure is a primitive array. - bool inPrimitiveArray() const { return getFieldDesc()->isPrimitiveArray(); } - /// Checks if the structure is an array of unknown size. - bool isUnknownSizeArray() const { - return getFieldDesc()->isUnknownSizeArray(); - } - /// Checks if the pointer points to an array. - bool isArrayElement() const { return Base != Offset; } - /// Pointer points directly to a block. - bool isRoot() const { - return (Base == 0 || Base == RootPtrMark) && Offset == 0; - } - - /// Returns the record descriptor of a class. - Record *getRecord() const { return getFieldDesc()->ElemRecord; } - /// Returns the field information. - const FieldDecl *getField() const { return getFieldDesc()->asFieldDecl(); } - - /// Checks if the object is a union. - bool isUnion() const; - - /// Checks if the storage is extern. - bool isExtern() const { return Pointee->isExtern(); } - /// Checks if the storage is static. - bool isStatic() const { return Pointee->isStatic(); } - /// Checks if the storage is temporary. - bool isTemporary() const { return Pointee->isTemporary(); } - /// Checks if the storage is a static temporary. - bool isStaticTemporary() const { return isStatic() && isTemporary(); } - - /// Checks if the field is mutable. - bool isMutable() const { return Base != 0 && getInlineDesc()->IsMutable; } - /// Checks if an object was initialized. - bool isInitialized() const; - /// Checks if the object is active. - bool isActive() const { return Base == 0 || getInlineDesc()->IsActive; } - /// Checks if a structure is a base class. - bool isBaseClass() const { return isField() && getInlineDesc()->IsBase; } - - /// Checks if an object or a subfield is mutable. - bool isConst() const { - return Base == 0 ? getDeclDesc()->IsConst : getInlineDesc()->IsConst; - } - - /// Returns the declaration ID. - llvm::Optional<unsigned> getDeclID() const { return Pointee->getDeclID(); } - - /// Returns the byte offset from the start. - unsigned getByteOffset() const { - return Offset; - } - - /// Returns the number of elements. - unsigned getNumElems() const { return getSize() / elemSize(); } - - /// Returns the index into an array. - int64_t getIndex() const { - if (isElementPastEnd()) - return 1; - if (auto ElemSize = elemSize()) - return getOffset() / ElemSize; - return 0; - } - - /// Checks if the index is one past end. - bool isOnePastEnd() const { - return isElementPastEnd() || getSize() == getOffset(); - } - - /// Checks if the pointer is an out-of-bounds element pointer. - bool isElementPastEnd() const { return Offset == PastEndMark; } - - /// Dereferences the pointer, if it's live. - template <typename T> T &deref() const { - assert(isLive() && "Invalid pointer"); - return *reinterpret_cast<T *>(Pointee->data() + Offset); - } - - /// Dereferences a primitive element. - template <typename T> T &elem(unsigned I) const { - return reinterpret_cast<T *>(Pointee->data())[I]; - } - - /// Initializes a field. - void initialize() const; - /// Activats a field. - void activate() const; - /// Deactivates an entire strurcutre. - void deactivate() const; - - /// Checks if two pointers are comparable. - static bool hasSameBase(const Pointer &A, const Pointer &B); - /// Checks if two pointers can be subtracted. - static bool hasSameArray(const Pointer &A, const Pointer &B); - - /// Prints the pointer. - void print(llvm::raw_ostream &OS) const { - OS << "{" << Base << ", " << Offset << ", "; - if (Pointee) - OS << Pointee->getSize(); - else - OS << "nullptr"; - OS << "}"; - } - -private: - friend class Block; - friend class DeadBlock; - - Pointer(Block *Pointee, unsigned Base, unsigned Offset); - - /// Returns the embedded descriptor preceding a field. - InlineDescriptor *getInlineDesc() const { return getDescriptor(Base); } - - /// Returns a descriptor at a given offset. - InlineDescriptor *getDescriptor(unsigned Offset) const { - assert(Offset != 0 && "Not a nested pointer"); - return reinterpret_cast<InlineDescriptor *>(Pointee->data() + Offset) - 1; - } - - /// Returns a reference to the pointer which stores the initialization map. - InitMap *&getInitMap() const { - return *reinterpret_cast<InitMap **>(Pointee->data() + Base); - } - - /// The block the pointer is pointing to. - Block *Pointee = nullptr; - /// Start of the current subfield. - unsigned Base = 0; - /// Offset into the block. - unsigned Offset = 0; - - /// Previous link in the pointer chain. - Pointer *Prev = nullptr; - /// Next link in the pointer chain. - Pointer *Next = nullptr; -}; - -inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Pointer &P) { - P.print(OS); - return OS; -} - -} // namespace interp -} // namespace clang - -#endif |