clang 17.0.0git
InterpBlock.h
Go to the documentation of this file.
1//===-- InterpBlock.h - Allocated blocks for the interpreter -*- C++ ----*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Defines the classes describing allocated blocks.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_INTERP_BLOCK_H
14#define LLVM_CLANG_AST_INTERP_BLOCK_H
15
16#include "Descriptor.h"
17#include "clang/AST/Decl.h"
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/Expr.h"
21#include "llvm/ADT/PointerUnion.h"
22#include "llvm/Support/raw_ostream.h"
23
24namespace clang {
25namespace interp {
26class Block;
27class DeadBlock;
28class InterpState;
29class Pointer;
30enum PrimType : unsigned;
31
32/// A memory block, either on the stack or in the heap.
33///
34/// The storage described by the block is immediately followed by
35/// optional metadata, which is followed by the actual data.
36///
37/// Block* rawData() data()
38/// │ │ │
39/// │ │ │
40/// ▼ ▼ ▼
41/// ┌───────────────┬─────────────────────────┬─────────────────┐
42/// │ Block │ Metadata │ Data │
43/// │ sizeof(Block) │ Desc->getMetadataSize() │ Desc->getSize() │
44/// └───────────────┴─────────────────────────┴─────────────────┘
45///
46/// Desc->getAllocSize() describes the size after the Block, i.e.
47/// the data size and the metadata size.
48///
49class Block final {
50public:
51 // Creates a new block.
52 Block(const std::optional<unsigned> &DeclID, Descriptor *Desc,
53 bool IsStatic = false, bool IsExtern = false)
55
56 Block(Descriptor *Desc, bool IsStatic = false, bool IsExtern = false)
58 Desc(Desc) {}
59
60 /// Returns the block's descriptor.
61 Descriptor *getDescriptor() const { return Desc; }
62 /// Checks if the block has any live pointers.
63 bool hasPointers() const { return Pointers; }
64 /// Checks if the block is extern.
65 bool isExtern() const { return IsExtern; }
66 /// Checks if the block has static storage duration.
67 bool isStatic() const { return IsStatic; }
68 /// Checks if the block is temporary.
69 bool isTemporary() const { return Desc->IsTemporary; }
70 /// Returns the size of the block.
71 unsigned getSize() const { return Desc->getAllocSize(); }
72 /// Returns the declaration ID.
73 std::optional<unsigned> getDeclID() const { return DeclID; }
74
75 /// Returns a pointer to the stored data.
76 /// You are allowed to read Desc->getSize() bytes from this address.
77 char *data() {
78 // rawData might contain metadata as well.
79 size_t DataOffset = Desc->getMetadataSize();
80 return rawData() + DataOffset;
81 }
82 const char *data() const {
83 // rawData might contain metadata as well.
84 size_t DataOffset = Desc->getMetadataSize();
85 return rawData() + DataOffset;
86 }
87
88 /// Returns a pointer to the raw data, including metadata.
89 /// You are allowed to read Desc->getAllocSize() bytes from this address.
90 char *rawData() { return reinterpret_cast<char *>(this) + sizeof(Block); }
91 const char *rawData() const {
92 return reinterpret_cast<const char *>(this) + sizeof(Block);
93 }
94
95 /// Returns a view over the data.
96 template <typename T>
97 T &deref() { return *reinterpret_cast<T *>(data()); }
98
99 /// Invokes the constructor.
100 void invokeCtor() {
101 std::memset(rawData(), 0, Desc->getAllocSize());
102 if (Desc->CtorFn)
104 /*isActive=*/true, Desc);
105 }
106
107 // Invokes the Destructor.
108 void invokeDtor() {
109 if (Desc->DtorFn)
110 Desc->DtorFn(this, data(), Desc);
111 }
112
113protected:
114 friend class Pointer;
115 friend class DeadBlock;
116 friend class InterpState;
117
120
121 // Deletes a dead block at the end of its lifetime.
122 void cleanup();
123
124 // Pointer chain management.
125 void addPointer(Pointer *P);
126 void removePointer(Pointer *P);
127 void movePointer(Pointer *From, Pointer *To);
128
129 /// Start of the chain of pointers.
130 Pointer *Pointers = nullptr;
131 /// Unique identifier of the declaration.
132 std::optional<unsigned> DeclID;
133 /// Flag indicating if the block has static storage duration.
134 bool IsStatic = false;
135 /// Flag indicating if the block is an extern.
136 bool IsExtern = false;
137 /// Flag indicating if the pointer is dead.
138 bool IsDead = false;
139 /// Pointer to the stack slot descriptor.
141};
142
143/// Descriptor for a dead block.
144///
145/// Dead blocks are chained in a double-linked list to deallocate them
146/// whenever pointers become dead.
147class DeadBlock final {
148public:
149 /// Copies the block.
150 DeadBlock(DeadBlock *&Root, Block *Blk);
151
152 /// Returns a pointer to the stored data.
153 char *data() { return B.data(); }
154
155private:
156 friend class Block;
157 friend class InterpState;
158
159 void free();
160
161 /// Root pointer of the list.
162 DeadBlock *&Root;
163 /// Previous block in the list.
164 DeadBlock *Prev;
165 /// Next block in the list.
166 DeadBlock *Next;
167
168 /// Actual block storing data and tracking pointers.
169 Block B;
170};
171
172} // namespace interp
173} // namespace clang
174
175#endif
StringRef P
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
A memory block, either on the stack or in the heap.
Definition: InterpBlock.h:49
unsigned getSize() const
Returns the size of the block.
Definition: InterpBlock.h:71
bool IsExtern
Flag indicating if the block is an extern.
Definition: InterpBlock.h:136
void movePointer(Pointer *From, Pointer *To)
Definition: InterpBlock.cpp:47
void addPointer(Pointer *P)
Definition: InterpBlock.cpp:21
Descriptor * getDescriptor() const
Returns the block's descriptor.
Definition: InterpBlock.h:61
bool isExtern() const
Checks if the block is extern.
Definition: InterpBlock.h:65
Block(Descriptor *Desc, bool IsStatic=false, bool IsExtern=false)
Definition: InterpBlock.h:56
Descriptor * Desc
Pointer to the stack slot descriptor.
Definition: InterpBlock.h:140
void removePointer(Pointer *P)
Definition: InterpBlock.cpp:31
void invokeCtor()
Invokes the constructor.
Definition: InterpBlock.h:100
bool isStatic() const
Checks if the block has static storage duration.
Definition: InterpBlock.h:67
const char * rawData() const
Definition: InterpBlock.h:91
const char * data() const
Definition: InterpBlock.h:82
bool isTemporary() const
Checks if the block is temporary.
Definition: InterpBlock.h:69
T & deref()
Returns a view over the data.
Definition: InterpBlock.h:97
bool IsStatic
Flag indicating if the block has static storage duration.
Definition: InterpBlock.h:134
Pointer * Pointers
Start of the chain of pointers.
Definition: InterpBlock.h:130
Block(const std::optional< unsigned > &DeclID, Descriptor *Desc, bool IsStatic=false, bool IsExtern=false)
Definition: InterpBlock.h:52
Block(Descriptor *Desc, bool IsExtern, bool IsStatic, bool IsDead)
Definition: InterpBlock.h:118
bool IsDead
Flag indicating if the pointer is dead.
Definition: InterpBlock.h:138
char * rawData()
Returns a pointer to the raw data, including metadata.
Definition: InterpBlock.h:90
std::optional< unsigned > DeclID
Unique identifier of the declaration.
Definition: InterpBlock.h:132
std::optional< unsigned > getDeclID() const
Returns the declaration ID.
Definition: InterpBlock.h:73
char * data()
Returns a pointer to the stored data.
Definition: InterpBlock.h:77
bool hasPointers() const
Checks if the block has any live pointers.
Definition: InterpBlock.h:63
Descriptor for a dead block.
Definition: InterpBlock.h:147
char * data()
Returns a pointer to the stored data.
Definition: InterpBlock.h:153
Interpreter context.
Definition: InterpState.h:34
A pointer to a memory block, live or dead.
Definition: Pointer.h:61
PrimType
Enumeration of the primitive types of the VM.
Definition: PrimType.h:29
#define true
Definition: stdbool.h:21
Describes a memory block created by an allocation site.
Definition: Descriptor.h:76
const bool IsConst
Flag indicating if the block is mutable.
Definition: Descriptor.h:104
unsigned getAllocSize() const
Returns the allocated size, including metadata.
Definition: Descriptor.h:164
const BlockDtorFn DtorFn
Definition: Descriptor.h:114
const BlockCtorFn CtorFn
Storage management methods.
Definition: Descriptor.h:113
unsigned getMetadataSize() const
Returns the size of the metadata.
Definition: Descriptor.h:168
const bool IsMutable
Flag indicating if a field is mutable.
Definition: Descriptor.h:106
const bool IsTemporary
Flag indicating if the block is a temporary.
Definition: Descriptor.h:108