Home | History | Annotate | Line # | Download | only in Interp
      1  1.1  joerg //===-- InterpBlock.h - Allocated blocks for the interpreter -*- C++ ----*-===//
      2  1.1  joerg //
      3  1.1  joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4  1.1  joerg // See https://llvm.org/LICENSE.txt for license information.
      5  1.1  joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6  1.1  joerg //
      7  1.1  joerg //===----------------------------------------------------------------------===//
      8  1.1  joerg //
      9  1.1  joerg // Defines the classes describing allocated blocks.
     10  1.1  joerg //
     11  1.1  joerg //===----------------------------------------------------------------------===//
     12  1.1  joerg 
     13  1.1  joerg #ifndef LLVM_CLANG_AST_INTERP_BLOCK_H
     14  1.1  joerg #define LLVM_CLANG_AST_INTERP_BLOCK_H
     15  1.1  joerg 
     16  1.1  joerg #include "Descriptor.h"
     17  1.1  joerg #include "clang/AST/Decl.h"
     18  1.1  joerg #include "clang/AST/DeclCXX.h"
     19  1.1  joerg #include "clang/AST/Expr.h"
     20  1.1  joerg #include "clang/AST/ComparisonCategories.h"
     21  1.1  joerg #include "llvm/ADT/PointerUnion.h"
     22  1.1  joerg #include "llvm/Support/raw_ostream.h"
     23  1.1  joerg 
     24  1.1  joerg namespace clang {
     25  1.1  joerg namespace interp {
     26  1.1  joerg class Block;
     27  1.1  joerg class DeadBlock;
     28  1.1  joerg class Context;
     29  1.1  joerg class InterpState;
     30  1.1  joerg class Pointer;
     31  1.1  joerg class Function;
     32  1.1  joerg enum PrimType : unsigned;
     33  1.1  joerg 
     34  1.1  joerg /// A memory block, either on the stack or in the heap.
     35  1.1  joerg ///
     36  1.1  joerg /// The storage described by the block immediately follows it in memory.
     37  1.1  joerg class Block {
     38  1.1  joerg public:
     39  1.1  joerg   // Creates a new block.
     40  1.1  joerg   Block(const llvm::Optional<unsigned> &DeclID, Descriptor *Desc,
     41  1.1  joerg         bool IsStatic = false, bool IsExtern = false)
     42  1.1  joerg       : DeclID(DeclID), IsStatic(IsStatic), IsExtern(IsExtern), Desc(Desc) {}
     43  1.1  joerg 
     44  1.1  joerg   Block(Descriptor *Desc, bool IsStatic = false, bool IsExtern = false)
     45  1.1  joerg       : DeclID((unsigned)-1), IsStatic(IsStatic), IsExtern(IsExtern),
     46  1.1  joerg         Desc(Desc) {}
     47  1.1  joerg 
     48  1.1  joerg   /// Returns the block's descriptor.
     49  1.1  joerg   Descriptor *getDescriptor() const { return Desc; }
     50  1.1  joerg   /// Checks if the block has any live pointers.
     51  1.1  joerg   bool hasPointers() const { return Pointers; }
     52  1.1  joerg   /// Checks if the block is extern.
     53  1.1  joerg   bool isExtern() const { return IsExtern; }
     54  1.1  joerg   /// Checks if the block has static storage duration.
     55  1.1  joerg   bool isStatic() const { return IsStatic; }
     56  1.1  joerg   /// Checks if the block is temporary.
     57  1.1  joerg   bool isTemporary() const { return Desc->IsTemporary; }
     58  1.1  joerg   /// Returns the size of the block.
     59  1.1  joerg   InterpSize getSize() const { return Desc->getAllocSize(); }
     60  1.1  joerg   /// Returns the declaration ID.
     61  1.1  joerg   llvm::Optional<unsigned> getDeclID() const { return DeclID; }
     62  1.1  joerg 
     63  1.1  joerg   /// Returns a pointer to the stored data.
     64  1.1  joerg   char *data() { return reinterpret_cast<char *>(this + 1); }
     65  1.1  joerg 
     66  1.1  joerg   /// Returns a view over the data.
     67  1.1  joerg   template <typename T>
     68  1.1  joerg   T &deref() { return *reinterpret_cast<T *>(data()); }
     69  1.1  joerg 
     70  1.1  joerg   /// Invokes the constructor.
     71  1.1  joerg   void invokeCtor() {
     72  1.1  joerg     std::memset(data(), 0, getSize());
     73  1.1  joerg     if (Desc->CtorFn)
     74  1.1  joerg       Desc->CtorFn(this, data(), Desc->IsConst, Desc->IsMutable,
     75  1.1  joerg                    /*isActive=*/true, Desc);
     76  1.1  joerg   }
     77  1.1  joerg 
     78  1.1  joerg protected:
     79  1.1  joerg   friend class Pointer;
     80  1.1  joerg   friend class DeadBlock;
     81  1.1  joerg   friend class InterpState;
     82  1.1  joerg 
     83  1.1  joerg   Block(Descriptor *Desc, bool IsExtern, bool IsStatic, bool IsDead)
     84  1.1  joerg     : IsStatic(IsStatic), IsExtern(IsExtern), IsDead(true), Desc(Desc) {}
     85  1.1  joerg 
     86  1.1  joerg   // Deletes a dead block at the end of its lifetime.
     87  1.1  joerg   void cleanup();
     88  1.1  joerg 
     89  1.1  joerg   // Pointer chain management.
     90  1.1  joerg   void addPointer(Pointer *P);
     91  1.1  joerg   void removePointer(Pointer *P);
     92  1.1  joerg   void movePointer(Pointer *From, Pointer *To);
     93  1.1  joerg 
     94  1.1  joerg   /// Start of the chain of pointers.
     95  1.1  joerg   Pointer *Pointers = nullptr;
     96  1.1  joerg   /// Unique identifier of the declaration.
     97  1.1  joerg   llvm::Optional<unsigned> DeclID;
     98  1.1  joerg   /// Flag indicating if the block has static storage duration.
     99  1.1  joerg   bool IsStatic = false;
    100  1.1  joerg   /// Flag indicating if the block is an extern.
    101  1.1  joerg   bool IsExtern = false;
    102  1.1  joerg   /// Flag indicating if the pointer is dead.
    103  1.1  joerg   bool IsDead = false;
    104  1.1  joerg   /// Pointer to the stack slot descriptor.
    105  1.1  joerg   Descriptor *Desc;
    106  1.1  joerg };
    107  1.1  joerg 
    108  1.1  joerg /// Descriptor for a dead block.
    109  1.1  joerg ///
    110  1.1  joerg /// Dead blocks are chained in a double-linked list to deallocate them
    111  1.1  joerg /// whenever pointers become dead.
    112  1.1  joerg class DeadBlock {
    113  1.1  joerg public:
    114  1.1  joerg   /// Copies the block.
    115  1.1  joerg   DeadBlock(DeadBlock *&Root, Block *Blk);
    116  1.1  joerg 
    117  1.1  joerg   /// Returns a pointer to the stored data.
    118  1.1  joerg   char *data() { return B.data(); }
    119  1.1  joerg 
    120  1.1  joerg private:
    121  1.1  joerg   friend class Block;
    122  1.1  joerg   friend class InterpState;
    123  1.1  joerg 
    124  1.1  joerg   void free();
    125  1.1  joerg 
    126  1.1  joerg   /// Root pointer of the list.
    127  1.1  joerg   DeadBlock *&Root;
    128  1.1  joerg   /// Previous block in the list.
    129  1.1  joerg   DeadBlock *Prev;
    130  1.1  joerg   /// Next block in the list.
    131  1.1  joerg   DeadBlock *Next;
    132  1.1  joerg 
    133  1.1  joerg   /// Actual block storing data and tracking pointers.
    134  1.1  joerg   Block B;
    135  1.1  joerg };
    136  1.1  joerg 
    137  1.1  joerg } // namespace interp
    138  1.1  joerg } // namespace clang
    139  1.1  joerg 
    140  1.1  joerg #endif
    141