clang 19.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, const Descriptor *Desc,
53 bool IsStatic = false, bool IsExtern = false)
55 assert(Desc);
56 }
57
58 Block(const Descriptor *Desc, bool IsStatic = false, bool IsExtern = false)
60 Desc(Desc) {
61 assert(Desc);
62 }
63
64 /// Returns the block's descriptor.
65 const Descriptor *getDescriptor() const { return Desc; }
66 /// Checks if the block has any live pointers.
67 bool hasPointers() const { return Pointers; }
68 /// Checks if the block is extern.
69 bool isExtern() const { return IsExtern; }
70 /// Checks if the block has static storage duration.
71 bool isStatic() const { return IsStatic; }
72 /// Checks if the block is temporary.
73 bool isTemporary() const { return Desc->IsTemporary; }
74 /// Returns the size of the block.
75 unsigned getSize() const { return Desc->getAllocSize(); }
76 /// Returns the declaration ID.
77 std::optional<unsigned> getDeclID() const { return DeclID; }
78 bool isInitialized() const { return IsInitialized; }
79
80 /// Returns a pointer to the stored data.
81 /// You are allowed to read Desc->getSize() bytes from this address.
82 std::byte *data() {
83 // rawData might contain metadata as well.
84 size_t DataOffset = Desc->getMetadataSize();
85 return rawData() + DataOffset;
86 }
87 const std::byte *data() const {
88 // rawData might contain metadata as well.
89 size_t DataOffset = Desc->getMetadataSize();
90 return rawData() + DataOffset;
91 }
92
93 /// Returns a pointer to the raw data, including metadata.
94 /// You are allowed to read Desc->getAllocSize() bytes from this address.
95 std::byte *rawData() {
96 return reinterpret_cast<std::byte *>(this) + sizeof(Block);
97 }
98 const std::byte *rawData() const {
99 return reinterpret_cast<const std::byte *>(this) + sizeof(Block);
100 }
101
102 /// Returns a view over the data.
103 template <typename T>
104 T &deref() { return *reinterpret_cast<T *>(data()); }
105 template <typename T> const T &deref() const {
106 return *reinterpret_cast<const T *>(data());
107 }
108
109 /// Invokes the constructor.
110 void invokeCtor() {
111 std::memset(rawData(), 0, Desc->getAllocSize());
112 if (Desc->CtorFn)
114 /*isActive=*/true, Desc);
115 IsInitialized = true;
116 }
117
118 /// Invokes the Destructor.
119 void invokeDtor() {
120 if (Desc->DtorFn)
121 Desc->DtorFn(this, data(), Desc);
122 IsInitialized = false;
123 }
124
125 void dump() const { dump(llvm::errs()); }
126 void dump(llvm::raw_ostream &OS) const;
127
128protected:
129 friend class Pointer;
130 friend class DeadBlock;
131 friend class InterpState;
132
133 Block(const Descriptor *Desc, bool IsExtern, bool IsStatic, bool IsDead)
135
136 /// Deletes a dead block at the end of its lifetime.
137 void cleanup();
138
139 /// Pointer chain management.
140 void addPointer(Pointer *P);
141 void removePointer(Pointer *P);
142 void replacePointer(Pointer *Old, Pointer *New);
143#ifndef NDEBUG
144 bool hasPointer(const Pointer *P) const;
145#endif
146
147 /// Start of the chain of pointers.
148 Pointer *Pointers = nullptr;
149 /// Unique identifier of the declaration.
150 std::optional<unsigned> DeclID;
151 /// Flag indicating if the block has static storage duration.
152 bool IsStatic = false;
153 /// Flag indicating if the block is an extern.
154 bool IsExtern = false;
155 /// Flag indicating if the pointer is dead. This is only ever
156 /// set once, when converting the Block to a DeadBlock.
157 bool IsDead = false;
158 /// Flag indicating if the block contents have been initialized
159 /// via invokeCtor.
160 bool IsInitialized = false;
161 /// Pointer to the stack slot descriptor.
163};
164
165/// Descriptor for a dead block.
166///
167/// Dead blocks are chained in a double-linked list to deallocate them
168/// whenever pointers become dead.
169class DeadBlock final {
170public:
171 /// Copies the block.
172 DeadBlock(DeadBlock *&Root, Block *Blk);
173
174 /// Returns a pointer to the stored data.
175 std::byte *data() { return B.data(); }
176 std::byte *rawData() { return B.rawData(); }
177
178private:
179 friend class Block;
180 friend class InterpState;
181
182 void free();
183
184 /// Root pointer of the list.
185 DeadBlock *&Root;
186 /// Previous block in the list.
187 DeadBlock *Prev;
188 /// Next block in the list.
189 DeadBlock *Next;
190
191 /// Actual block storing data and tracking pointers.
192 Block B;
193};
194
195} // namespace interp
196} // namespace clang
197
198#endif
StringRef P
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
const CFGBlock * Block
Definition: HTMLLogger.cpp:153
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:75
const Descriptor * Desc
Pointer to the stack slot descriptor.
Definition: InterpBlock.h:162
bool IsExtern
Flag indicating if the block is an extern.
Definition: InterpBlock.h:154
void addPointer(Pointer *P)
Pointer chain management.
Definition: InterpBlock.cpp:19
void replacePointer(Pointer *Old, Pointer *New)
Definition: InterpBlock.cpp:61
void invokeDtor()
Invokes the Destructor.
Definition: InterpBlock.h:119
const T & deref() const
Definition: InterpBlock.h:105
bool isExtern() const
Checks if the block is extern.
Definition: InterpBlock.h:69
Block(const Descriptor *Desc, bool IsExtern, bool IsStatic, bool IsDead)
Definition: InterpBlock.h:133
Block(const std::optional< unsigned > &DeclID, const Descriptor *Desc, bool IsStatic=false, bool IsExtern=false)
Creates a new block.
Definition: InterpBlock.h:52
std::byte * data()
Returns a pointer to the stored data.
Definition: InterpBlock.h:82
Block(const Descriptor *Desc, bool IsStatic=false, bool IsExtern=false)
Definition: InterpBlock.h:58
const Descriptor * getDescriptor() const
Returns the block's descriptor.
Definition: InterpBlock.h:65
bool hasPointer(const Pointer *P) const
Definition: InterpBlock.cpp:85
void removePointer(Pointer *P)
Definition: InterpBlock.cpp:36
const std::byte * rawData() const
Definition: InterpBlock.h:98
bool IsInitialized
Flag indicating if the block contents have been initialized via invokeCtor.
Definition: InterpBlock.h:160
void invokeCtor()
Invokes the constructor.
Definition: InterpBlock.h:110
bool isStatic() const
Checks if the block has static storage duration.
Definition: InterpBlock.h:71
bool isTemporary() const
Checks if the block is temporary.
Definition: InterpBlock.h:73
std::byte * rawData()
Returns a pointer to the raw data, including metadata.
Definition: InterpBlock.h:95
const std::byte * data() const
Definition: InterpBlock.h:87
bool isInitialized() const
Definition: InterpBlock.h:78
T & deref()
Returns a view over the data.
Definition: InterpBlock.h:104
void cleanup()
Deletes a dead block at the end of its lifetime.
Definition: InterpBlock.cpp:56
bool IsStatic
Flag indicating if the block has static storage duration.
Definition: InterpBlock.h:152
Pointer * Pointers
Start of the chain of pointers.
Definition: InterpBlock.h:148
void dump() const
Definition: InterpBlock.h:125
bool IsDead
Flag indicating if the pointer is dead.
Definition: InterpBlock.h:157
std::optional< unsigned > DeclID
Unique identifier of the declaration.
Definition: InterpBlock.h:150
std::optional< unsigned > getDeclID() const
Returns the declaration ID.
Definition: InterpBlock.h:77
bool hasPointers() const
Checks if the block has any live pointers.
Definition: InterpBlock.h:67
Descriptor for a dead block.
Definition: InterpBlock.h:169
std::byte * data()
Returns a pointer to the stored data.
Definition: InterpBlock.h:175
Interpreter context.
Definition: InterpState.h:35
A pointer to a memory block, live or dead.
Definition: Pointer.h:80
PrimType
Enumeration of the primitive types of the VM.
Definition: PrimType.h:32
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
#define true
Definition: stdbool.h:25
Describes a memory block created by an allocation site.
Definition: Descriptor.h:91
const bool IsConst
Flag indicating if the block is mutable.
Definition: Descriptor.h:123
unsigned getAllocSize() const
Returns the allocated size, including metadata.
Definition: Descriptor.h:204
const BlockDtorFn DtorFn
Definition: Descriptor.h:135
const BlockCtorFn CtorFn
Storage management methods.
Definition: Descriptor.h:134
unsigned getMetadataSize() const
Returns the size of the metadata.
Definition: Descriptor.h:208
const bool IsMutable
Flag indicating if a field is mutable.
Definition: Descriptor.h:125
const bool IsTemporary
Flag indicating if the block is a temporary.
Definition: Descriptor.h:127