@@ -136,7 +136,7 @@ template <typename CursorType> constexpr CursorIndex cursorIndex(CursorType C) {
136
136
// / An indicator of whether a Syntax node was found or written in the source.
137
137
// /
138
138
// / This is not an 'implicit' bit.
139
- enum class SourcePresence {
139
+ enum class SourcePresence : uint8_t {
140
140
// / The syntax was authored by a human and found, or was generated.
141
141
Present,
142
142
@@ -164,52 +164,54 @@ class RawSyntax final
164
164
// / have a manually specified id
165
165
static SyntaxNodeId NextFreeNodeId;
166
166
167
- // / An ID of this node that is stable across incremental parses
168
- SyntaxNodeId NodeId;
169
-
170
167
// / The \c SyntaxArena in which this node was allocated.
171
168
SyntaxArena *Arena;
172
169
173
- union {
174
- struct {
175
- // / Number of bytes this node takes up spelled out in the source code.
176
- // / Always 0 if the node is missing.
177
- unsigned TextLength : 32 ;
178
- // / Whether this piece of syntax was actually present in the source.
179
- unsigned Presence : 1 ;
180
- unsigned IsToken : 1 ;
181
- } Common;
182
- enum { NumRawSyntaxBits = 32 + 1 + 1 };
183
-
184
- // For "layout" nodes.
185
- struct {
186
- static_assert (NumRawSyntaxBits <= 64 ,
187
- " Only 64 bits reserved for standard syntax bits" );
188
- uint64_t : bitmax(NumRawSyntaxBits, 64 ); // align to 32 bits
189
- // / Number of children this "layout" node has.
190
- unsigned NumChildren : 32 ;
191
- // / Total number of sub nodes, i.e. number of transitive children of this
192
- // / node. This does not include the node itself.
193
- unsigned TotalSubNodeCount : 32 ;
194
- // / The kind of syntax this node represents.
195
- unsigned Kind : bitmax(NumSyntaxKindBits, 8 );
196
- } Layout;
197
-
198
- // For "token" nodes.
199
- struct {
200
- static_assert (NumRawSyntaxBits <= 64 ,
201
- " Only 64 bits reserved for standard syntax bits" );
202
- uint64_t : bitmax(NumRawSyntaxBits, 64 ); // align to 16 bits
203
- // / The kind of token this "token" node represents.
204
- const char *LeadingTrivia;
205
- const char *TokenText;
206
- const char *TrailingTrivia;
207
- unsigned LeadingTriviaLength : 32 ;
208
- unsigned TokenLength : 32 ;
209
- unsigned TrailingTriviaLength : 32 ;
210
- unsigned TokenKind : 16 ;
211
- } Token;
212
- } Bits;
170
+ // / An ID of this node that is stable across incremental parses
171
+ SyntaxNodeId NodeId;
172
+
173
+ // / Number of bytes this node takes up spelled out in the source code.
174
+ // / Always 0 if the node is missing.
175
+ uint32_t TextLength;
176
+
177
+ // / Whether this piece of syntax was actually present in the source.
178
+ SourcePresence Presence;
179
+
180
+ // / Whether this node is a token or layout node. Determines if \c Bits should
181
+ // / be interpreted as \c LayoutData or \c TokenData.
182
+ bool IsToken;
183
+
184
+ struct LayoutData {
185
+ // / Number of children this "layout" node has.
186
+ uint32_t NumChildren;
187
+ // / Total number of sub nodes, i.e. number of transitive children of this
188
+ // / node. This does not include the node itself.
189
+ uint32_t TotalSubNodeCount;
190
+ // / The kind of syntax this node represents.
191
+ SyntaxKind Kind;
192
+ };
193
+
194
+ struct TokenData {
195
+ // / The pointers to the leading/trailing trivia and token texts. If their
196
+ // / lengths are greater than 0, these always reside in the node's \c Arena.
197
+ const char *LeadingTrivia;
198
+ const char *TokenText;
199
+ const char *TrailingTrivia;
200
+ uint32_t LeadingTriviaLength;
201
+ uint32_t TokenLength;
202
+ uint32_t TrailingTriviaLength;
203
+ // / The kind of token this "token" node represents.
204
+ tok TokenKind;
205
+ };
206
+
207
+ union BitsData {
208
+ LayoutData Layout;
209
+ TokenData Token;
210
+
211
+ BitsData (const LayoutData &Layout) : Layout (Layout) {}
212
+ BitsData (const TokenData &Token) : Token (Token) {}
213
+ };
214
+ BitsData Bits;
213
215
214
216
size_t numTrailingObjects (OverloadToken<const RawSyntax *>) const {
215
217
return isToken () ? 0 : Bits.Layout .NumChildren ;
@@ -224,17 +226,19 @@ class RawSyntax final
224
226
RawSyntax (SyntaxKind Kind, ArrayRef<const RawSyntax *> Layout,
225
227
size_t TextLength, SourcePresence Presence,
226
228
const RC<SyntaxArena> &Arena, llvm::Optional<SyntaxNodeId> NodeId)
227
- : Arena(Arena.get()),
228
- Bits({{unsigned (TextLength), unsigned (Presence), false }}) {
229
+ : Arena(Arena.get()), TextLength(uint32_t (TextLength)),
230
+ Presence (Presence), IsToken(false ),
231
+ Bits(LayoutData{uint32_t (Layout.size ()),
232
+ /* TotalSubNodeCount=*/ 0 , /* set in body*/
233
+ Kind}) {
229
234
assert (Arena && " RawSyntax nodes must always be allocated in an arena" );
230
235
assert (
231
236
Kind != SyntaxKind::Token &&
232
237
" 'token' syntax node must be constructed with dedicated constructor" );
233
238
234
- size_t TotalSubNodeCount = 0 ;
235
239
for (auto Child : Layout) {
236
240
if (Child) {
237
- TotalSubNodeCount += Child->getTotalSubNodeCount () + 1 ;
241
+ Bits. Layout . TotalSubNodeCount += Child->getTotalSubNodeCount () + 1 ;
238
242
// If the child is stored in a different arena, it needs to stay alive
239
243
// as long as this node's arena is alive.
240
244
Arena->addChildArena (Child->Arena );
@@ -247,9 +251,6 @@ class RawSyntax final
247
251
} else {
248
252
this ->NodeId = NextFreeNodeId++;
249
253
}
250
- Bits.Layout .NumChildren = Layout.size ();
251
- Bits.Layout .TotalSubNodeCount = TotalSubNodeCount;
252
- Bits.Layout .Kind = unsigned (Kind);
253
254
254
255
// Initialize layout data.
255
256
std::uninitialized_copy (Layout.begin (), Layout.end (),
@@ -265,8 +266,11 @@ class RawSyntax final
265
266
StringRef LeadingTrivia, StringRef TrailingTrivia,
266
267
SourcePresence Presence, const RC<SyntaxArena> &Arena,
267
268
llvm::Optional<SyntaxNodeId> NodeId)
268
- : Arena(Arena.get()),
269
- Bits({{unsigned (TextLength), unsigned (Presence), true }}) {
269
+ : Arena(Arena.get()), TextLength(uint32_t (TextLength)),
270
+ Presence(Presence), IsToken(true ),
271
+ Bits(TokenData{LeadingTrivia.data (), Text.data (), TrailingTrivia.data (),
272
+ uint32_t (LeadingTrivia.size ()), uint32_t (Text.size ()),
273
+ uint32_t (TrailingTrivia.size ()), TokKind}) {
270
274
assert (Arena && " RawSyntax nodes must always be allocated in an arena" );
271
275
272
276
if (Presence == SourcePresence::Missing) {
@@ -282,14 +286,6 @@ class RawSyntax final
282
286
} else {
283
287
this ->NodeId = NextFreeNodeId++;
284
288
}
285
- Bits.Token .LeadingTrivia = LeadingTrivia.data ();
286
- Bits.Token .TokenText = Text.data ();
287
- Bits.Token .TrailingTrivia = TrailingTrivia.data ();
288
- Bits.Token .LeadingTriviaLength = LeadingTrivia.size ();
289
- Bits.Token .TokenLength = Text.size ();
290
- Bits.Token .TrailingTriviaLength = TrailingTrivia.size ();
291
- Bits.Token .TokenKind = unsigned (TokKind);
292
-
293
289
Arena->copyStringToArenaIfNecessary (Bits.Token .LeadingTrivia ,
294
290
Bits.Token .LeadingTriviaLength );
295
291
Arena->copyStringToArenaIfNecessary (Bits.Token .TokenText ,
@@ -388,11 +384,11 @@ class RawSyntax final
388
384
RC<SyntaxArena> getArena () const { return RC<SyntaxArena>(Arena); }
389
385
390
386
SourcePresence getPresence () const {
391
- return static_cast <SourcePresence>(Bits. Common . Presence );
387
+ return static_cast <SourcePresence>(Presence);
392
388
}
393
389
394
390
SyntaxKind getKind () const {
395
- if (Bits. Common . IsToken ) {
391
+ if (isToken () ) {
396
392
return SyntaxKind::Token;
397
393
} else {
398
394
return static_cast <SyntaxKind>(Bits.Layout .Kind );
@@ -442,7 +438,7 @@ class RawSyntax final
442
438
bool isUnknown () const { return isUnknownKind (getKind ()); }
443
439
444
440
// / Return true if this raw syntax node is a token.
445
- bool isToken () const { return Bits. Common . IsToken ; }
441
+ bool isToken () const { return IsToken; }
446
442
447
443
// / \name Getter routines for SyntaxKind::Token.
448
444
// / @{
@@ -532,7 +528,7 @@ class RawSyntax final
532
528
533
529
// / Return the number of bytes this node takes when spelled out in the source
534
530
// / including trivia.
535
- size_t getTextLength () const { return Bits. Common . TextLength ; }
531
+ size_t getTextLength () const { return TextLength; }
536
532
537
533
// / @}
538
534
0 commit comments