clang 22.0.0git
CIRGenCleanup.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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// These classes support the generation of CIR for cleanups, initially based
10// on LLVM IR cleanup handling, but ought to change as CIR evolves.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef CLANG_LIB_CIR_CODEGEN_CIRGENCLEANUP_H
15#define CLANG_LIB_CIR_CODEGEN_CIRGENCLEANUP_H
16
17#include "Address.h"
18#include "EHScopeStack.h"
19#include "mlir/IR/Value.h"
20
21namespace clang::CIRGen {
22
23/// A protected scope for zero-cost EH handling.
24class EHScope {
25 class CommonBitFields {
26 friend class EHScope;
27 unsigned kind : 3;
28 };
29 enum { NumCommonBits = 3 };
30
31protected:
33 friend class EHCleanupScope;
34 unsigned : NumCommonBits;
35
36 /// Whether this cleanup needs to be run along normal edges.
37 unsigned isNormalCleanup : 1;
38
39 /// Whether this cleanup needs to be run along exception edges.
40 unsigned isEHCleanup : 1;
41
42 /// Whether this cleanup is currently active.
43 unsigned isActive : 1;
44
45 /// Whether this cleanup is a lifetime marker
46 unsigned isLifetimeMarker : 1;
47
48 /// Whether the normal cleanup should test the activation flag.
49 unsigned testFlagInNormalCleanup : 1;
50
51 /// Whether the EH cleanup should test the activation flag.
52 unsigned testFlagInEHCleanup : 1;
53
54 /// The amount of extra storage needed by the Cleanup.
55 /// Always a multiple of the scope-stack alignment.
56 unsigned cleanupSize : 12;
57 };
58
59 union {
60 CommonBitFields commonBits;
62 };
63
64public:
66
67 EHScope(Kind kind) { commonBits.kind = kind; }
68
69 Kind getKind() const { return static_cast<Kind>(commonBits.kind); }
70};
71
72/// A cleanup scope which generates the cleanup blocks lazily.
73class alignas(EHScopeStack::ScopeStackAlignment) EHCleanupScope
74 : public EHScope {
75public:
76 /// Gets the size required for a lazy cleanup scope with the given
77 /// cleanup-data requirements.
78 static size_t getSizeForCleanupSize(size_t size) {
79 return sizeof(EHCleanupScope) + size;
80 }
81
82 size_t getAllocatedSize() const {
83 return sizeof(EHCleanupScope) + cleanupBits.cleanupSize;
84 }
85
86 EHCleanupScope(unsigned cleanupSize) : EHScope(EHScope::Cleanup) {
87 // TODO(cir): When exception handling is upstreamed, isNormalCleanup and
88 // isEHCleanup will be arguments to the constructor.
89 cleanupBits.isNormalCleanup = true;
90 cleanupBits.isEHCleanup = false;
91 cleanupBits.isActive = true;
92 cleanupBits.isLifetimeMarker = false;
93 cleanupBits.testFlagInNormalCleanup = false;
94 cleanupBits.testFlagInEHCleanup = false;
95 cleanupBits.cleanupSize = cleanupSize;
96
97 assert(cleanupBits.cleanupSize == cleanupSize && "cleanup size overflow");
98 }
99
100 void destroy() {}
101 // Objects of EHCleanupScope are not destructed. Use destroy().
102 ~EHCleanupScope() = delete;
103
104 bool isNormalCleanup() const { return cleanupBits.isNormalCleanup; }
105
106 bool isActive() const { return cleanupBits.isActive; }
107
108 size_t getCleanupSize() const { return cleanupBits.cleanupSize; }
109 void *getCleanupBuffer() { return this + 1; }
110
112 return reinterpret_cast<EHScopeStack::Cleanup *>(getCleanupBuffer());
113 }
114
115 static bool classof(const EHScope *scope) {
116 return (scope->getKind() == Cleanup);
117 }
118
119 void markEmitted() {}
120};
121
122/// A non-stable pointer into the scope stack.
124 char *ptr = nullptr;
125
126 friend class EHScopeStack;
127 explicit iterator(char *ptr) : ptr(ptr) {}
128
129public:
130 iterator() = default;
131
132 EHScope *get() const { return reinterpret_cast<EHScope *>(ptr); }
133
134 EHScope &operator*() const { return *get(); }
135};
136
138 return iterator(startOfData);
139}
140
141} // namespace clang::CIRGen
142#endif // CLANG_LIB_CIR_CODEGEN_CIRGENCLEANUP_H
A cleanup scope which generates the cleanup blocks lazily.
Definition: CIRGenCleanup.h:74
EHScopeStack::Cleanup * getCleanup()
static bool classof(const EHScope *scope)
static size_t getSizeForCleanupSize(size_t size)
Gets the size required for a lazy cleanup scope with the given cleanup-data requirements.
Definition: CIRGenCleanup.h:78
EHCleanupScope(unsigned cleanupSize)
Definition: CIRGenCleanup.h:86
Information for lazily generating a cleanup.
Definition: EHScopeStack.h:93
A non-stable pointer into the scope stack.
A stack of scopes which respond to exceptions, including cleanups and catch blocks.
Definition: EHScopeStack.h:44
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
A protected scope for zero-cost EH handling.
Definition: CIRGenCleanup.h:24
CleanupBitFields cleanupBits
Definition: CIRGenCleanup.h:61
CommonBitFields commonBits
Definition: CIRGenCleanup.h:60