@@ -218,31 +218,41 @@ class RawSyntax final
218
218
}
219
219
220
220
// / Constructor for creating layout nodes.
221
- // / If the node has been allocated inside the bump allocator of a
222
- // / \c SyntaxArena, that arena must be passed as \p Arena to retain the node's
223
- // / underlying storage.
221
+ // / \p Children is an iterator that provides the child \c RawSyntax nodes.
222
+ // / It is only traversed once.
223
+ // / \p NumChildren is the number of elements provided by the \p Children
224
+ // / iterator.
224
225
// / If \p NodeId is \c None, the next free NodeId is used, if it is passed,
225
226
// / the caller needs to assure that the node ID has not been used yet.
226
- RawSyntax (SyntaxKind Kind, ArrayRef<const RawSyntax *> Layout,
227
- size_t TextLength, SourcePresence Presence,
227
+ template <typename ChildrenIteratorType>
228
+ RawSyntax (SyntaxKind Kind, ChildrenIteratorType ChildrenIt,
229
+ uint32_t NumChildren, SourcePresence Presence,
228
230
const RC<SyntaxArena> &Arena, llvm::Optional<SyntaxNodeId> NodeId)
229
- : Arena(Arena.get()), TextLength(uint32_t (TextLength) ),
231
+ : Arena(Arena.get()), TextLength(0 /* computed in body */ ),
230
232
Presence (Presence), IsToken(false ),
231
- Bits(LayoutData{uint32_t (Layout.size ()),
232
- /* TotalSubNodeCount=*/ 0 , /* set in body*/
233
- Kind}) {
233
+ Bits(LayoutData{NumChildren,
234
+ /* TotalSubNodeCount=*/ 0 /* computed in body*/ , Kind}) {
234
235
assert (Arena && " RawSyntax nodes must always be allocated in an arena" );
235
236
assert (
236
237
Kind != SyntaxKind::Token &&
237
238
" 'token' syntax node must be constructed with dedicated constructor" );
238
239
239
- for (auto Child : Layout) {
240
+ const RawSyntax **TrailingChildren =
241
+ getTrailingObjects<const RawSyntax *>();
242
+ for (uint32_t I = 0 ; I < NumChildren;
243
+ ++I, ++ChildrenIt, ++TrailingChildren) {
244
+ const RawSyntax *Child = *ChildrenIt;
240
245
if (Child) {
246
+ // Compute TextLength and TotalSubNodeCount of this node in place.
247
+ TextLength += Child->getTextLength ();
241
248
Bits.Layout .TotalSubNodeCount += Child->getTotalSubNodeCount () + 1 ;
249
+
242
250
// If the child is stored in a different arena, it needs to stay alive
243
251
// as long as this node's arena is alive.
244
252
Arena->addChildArena (Child->Arena );
245
253
}
254
+
255
+ *TrailingChildren = Child;
246
256
}
247
257
248
258
if (NodeId.hasValue ()) {
@@ -251,10 +261,6 @@ class RawSyntax final
251
261
} else {
252
262
this ->NodeId = NextFreeNodeId++;
253
263
}
254
-
255
- // Initialize layout data.
256
- std::uninitialized_copy (Layout.begin (), Layout.end (),
257
- getTrailingObjects<const RawSyntax *>());
258
264
}
259
265
260
266
// / Constructor for creating token nodes
@@ -311,28 +317,26 @@ class RawSyntax final
311
317
// / @{
312
318
313
319
// / Make a raw "layout" syntax node.
320
+ template <typename ChildrenIteratorType>
314
321
static const RawSyntax *
315
- make (SyntaxKind Kind, ArrayRef< const RawSyntax *> Layout , size_t TextLength ,
322
+ make (SyntaxKind Kind, ChildrenIteratorType ChildrenIt , size_t NumChildren ,
316
323
SourcePresence Presence, const RC<SyntaxArena> &Arena,
317
324
llvm::Optional<SyntaxNodeId> NodeId = llvm::None) {
318
325
assert (Arena && " RawSyntax nodes must always be allocated in an arena" );
319
- auto size = totalSizeToAlloc<const RawSyntax *>(Layout. size () );
326
+ auto size = totalSizeToAlloc<const RawSyntax *>(NumChildren );
320
327
void *data = Arena->Allocate (size, alignof (RawSyntax));
321
328
return new (data)
322
- RawSyntax (Kind, Layout, TextLength , Presence, Arena, NodeId);
329
+ RawSyntax (Kind, ChildrenIt, NumChildren , Presence, Arena, NodeId);
323
330
}
324
331
332
+ // / Convenience constructor to create a raw "layout" syntax node from an
333
+ // / \c llvm::ArrayRef containing the children.
325
334
static const RawSyntax *
326
- makeAndCalcLength (SyntaxKind Kind, ArrayRef<const RawSyntax *> Layout,
327
- SourcePresence Presence, const RC<SyntaxArena> &Arena,
328
- llvm::Optional<SyntaxNodeId> NodeId = llvm::None) {
329
- size_t TextLength = 0 ;
330
- for (auto Child : Layout) {
331
- if (Child) {
332
- TextLength += Child->getTextLength ();
333
- }
334
- }
335
- return make (Kind, Layout, TextLength, Presence, Arena, NodeId);
335
+ make (SyntaxKind Kind, llvm::ArrayRef<const RawSyntax *> Children,
336
+ SourcePresence Presence, const RC<SyntaxArena> &Arena,
337
+ llvm::Optional<SyntaxNodeId> NodeId = llvm::None) {
338
+ return make (Kind, Children.begin (), Children.size (), Presence, Arena,
339
+ NodeId);
336
340
}
337
341
338
342
// / Make a raw "token" syntax node.
@@ -367,7 +371,7 @@ class RawSyntax final
367
371
// / Make a missing raw "layout" syntax node.
368
372
static const RawSyntax *missing (SyntaxKind Kind,
369
373
const RC<SyntaxArena> &Arena) {
370
- return make (Kind, {}, /* TextLength= */ 0 , SourcePresence::Missing, Arena);
374
+ return make (Kind, {}, SourcePresence::Missing, Arena);
371
375
}
372
376
373
377
// / Make a missing raw "token" syntax node.
0 commit comments