28
28
#include < utility>
29
29
30
30
namespace llvm {
31
+ class BumpPtrAllocator ;
31
32
class SourceMgr ;
32
33
}
33
34
34
35
namespace swift {
36
+ class ASTContext ;
35
37
class BoundGenericType ;
36
38
class SourceLoc ;
37
39
class Type ;
@@ -71,7 +73,53 @@ class ProtocolConformance {
71
73
// / the requirements of those protocols.
72
74
llvm::DenseMap<ProtocolDecl *, ProtocolConformance *> InheritedMapping;
73
75
};
74
-
76
+
77
+ // / \brief The arena in which a particular ASTContext allocation will go.
78
+ enum class AllocationArena {
79
+ // / \brief The permanent arena, which is tied to the lifetime of
80
+ // / the ASTContext.
81
+ // /
82
+ // / All global declarations and types need to be allocated into this arena.
83
+ // / At present, everything that is not a type involving a type variable is
84
+ // / allocated in this arena.
85
+ Permanent,
86
+ // / \brief The constraint solver's temporary arena, which is tied to the
87
+ // / lifetime of a particular instance of the constraint solver.
88
+ // /
89
+ // / Any type involving a type variable is allocated in this arena.
90
+ ConstraintSolver
91
+ };
92
+
93
+ // / \brief Introduces a new constraint checker arena, whose lifetime is
94
+ // / tied to the lifetime of this RAII object.
95
+ class ConstraintCheckerArenaRAII {
96
+ ASTContext &Self;
97
+ void *Data;
98
+
99
+ public:
100
+ // / \brief Introduces a new constraint checker arena, supplanting any
101
+ // / existing constraint checker arena.
102
+ // /
103
+ // / \param self The ASTContext into which this constraint checker arena
104
+ // / will be installed.
105
+ // /
106
+ // / \param allocator The allocator used for allocating any data that
107
+ // / goes into the constraint checker arena.
108
+ ConstraintCheckerArenaRAII (ASTContext &self,
109
+ llvm::BumpPtrAllocator &allocator);
110
+
111
+ ConstraintCheckerArenaRAII (const ConstraintCheckerArenaRAII &) = delete ;
112
+ ConstraintCheckerArenaRAII (ConstraintCheckerArenaRAII &&) = delete ;
113
+
114
+ ConstraintCheckerArenaRAII &
115
+ operator =(const ConstraintCheckerArenaRAII &) = delete ;
116
+
117
+ ConstraintCheckerArenaRAII &
118
+ operator =(ConstraintCheckerArenaRAII &&) = delete ;
119
+
120
+ ~ConstraintCheckerArenaRAII ();
121
+ };
122
+
75
123
// / ASTContext - This object creates and owns the AST objects.
76
124
class ASTContext {
77
125
ASTContext (const ASTContext&) = delete ;
@@ -81,6 +129,8 @@ class ASTContext {
81
129
// Members that should only be used by ASTContext.cpp.
82
130
struct Implementation ;
83
131
Implementation &Impl;
132
+
133
+ friend class ConstraintCheckerArenaRAII ;
84
134
public:
85
135
86
136
ASTContext (LangOptions &langOpts, llvm::SourceMgr &SourceMgr,
@@ -113,47 +163,63 @@ class ASTContext {
113
163
// / ConformsTo - Caches the results of checking whether a given (canonical)
114
164
// / type conforms to a given protocol.
115
165
ConformsToMap ConformsTo;
166
+
167
+ // / \brief Retrieve the allocator for the given arena.
168
+ llvm::BumpPtrAllocator &
169
+ getAllocator (AllocationArena arena = AllocationArena::Permanent) const ;
116
170
117
171
// / Allocate - Allocate memory from the ASTContext bump pointer.
118
- void *Allocate (unsigned long Bytes, unsigned Alignment);
172
+ void *Allocate (unsigned long bytes, unsigned alignment,
173
+ AllocationArena arena = AllocationArena::Permanent) {
174
+ return getAllocator (arena).Allocate (bytes, alignment);
175
+ }
176
+
119
177
120
178
template <typename T>
121
- T *Allocate (unsigned NElts) {
122
- T *Res = (T*)Allocate (sizeof (T)*NElts, __alignof__ (T));
123
- for (unsigned i = 0 ; i != NElts; ++i)
124
- new (Res+i) T ();
125
- return Res;
179
+ T *Allocate (unsigned numElts,
180
+ AllocationArena arena = AllocationArena::Permanent) {
181
+ T *res = (T*)Allocate (sizeof (T)*numElts, __alignof__ (T), arena);
182
+ for (unsigned i = 0 ; i != numElts; ++i)
183
+ new (res+i) T ();
184
+ return res;
126
185
}
127
186
128
187
template <typename T, typename It>
129
- T *AllocateCopy (It Start, It End) {
130
- T *Res = (T*)Allocate (sizeof (T)*(End-Start), __alignof__ (T));
131
- for (unsigned i = 0 ; Start != End; ++Start, ++i)
132
- new (Res+i) T (*Start);
133
- return Res;
188
+ T *AllocateCopy (It start, It end,
189
+ AllocationArena arena = AllocationArena::Permanent) {
190
+ T *res = (T*)Allocate (sizeof (T)*(end-start), __alignof__ (T), arena);
191
+ for (unsigned i = 0 ; start != end; ++start, ++i)
192
+ new (res+i) T (*start);
193
+ return res;
134
194
}
135
195
136
196
template <typename T>
137
- ArrayRef<T> AllocateCopy (ArrayRef<T> Arr) {
138
- return ArrayRef<T>(AllocateCopy<T>(Arr.begin (), Arr.end ()),
139
- Arr.size ());
197
+ ArrayRef<T> AllocateCopy (ArrayRef<T> array,
198
+ AllocationArena arena = AllocationArena::Permanent) {
199
+ return ArrayRef<T>(AllocateCopy<T>(array.begin (), array.end (), arena),
200
+ array.size ());
140
201
}
141
202
142
203
template <typename T>
143
- MutableArrayRef<T> AllocateCopy (MutableArrayRef<T> Arr) {
144
- return MutableArrayRef<T>(AllocateCopy<T>(Arr.begin (), Arr.end ()),
145
- Arr.size ());
204
+ MutableArrayRef<T>
205
+ AllocateCopy (MutableArrayRef<T> array,
206
+ AllocationArena arena = AllocationArena::Permanent) {
207
+ return MutableArrayRef<T>(AllocateCopy<T>(array.begin (), array.end (),arena),
208
+ array.size ());
146
209
}
147
210
148
211
149
212
template <typename T>
150
- ArrayRef<T> AllocateCopy (const SmallVectorImpl<T> &Vec) {
151
- return AllocateCopy (ArrayRef<T>(Vec));
213
+ ArrayRef<T> AllocateCopy (const SmallVectorImpl<T> &vec,
214
+ AllocationArena arena = AllocationArena::Permanent) {
215
+ return AllocateCopy (ArrayRef<T>(vec), arena);
152
216
}
153
217
154
218
template <typename T>
155
- MutableArrayRef<T> AllocateCopy (SmallVectorImpl<T> &Vec) {
156
- return AllocateCopy (MutableArrayRef<T>(Vec));
219
+ MutableArrayRef<T>
220
+ AllocateCopy (SmallVectorImpl<T> &vec,
221
+ AllocationArena arena = AllocationArena::Permanent) {
222
+ return AllocateCopy (MutableArrayRef<T>(vec), arena);
157
223
}
158
224
159
225
0 commit comments