Skip to content

Commit a5632b4

Browse files
committed
[libSyntax] Create DeferredLayoutNode/DeferredTokenNode in ParsedRawSyntaxRecorder
This is an intermediate step in the effort to push deferred node handling all the way down to SyntaxParseActions.
1 parent bdacb68 commit a5632b4

File tree

2 files changed

+101
-104
lines changed

2 files changed

+101
-104
lines changed

include/swift/Parse/ParsedRawSyntaxNode.h

Lines changed: 58 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,17 @@ namespace swift {
2424

2525
typedef const void *OpaqueSyntaxNode;
2626
class SyntaxParsingContext;
27+
class ParsedRawSyntaxNode;
28+
29+
struct DeferredLayoutNode {
30+
MutableArrayRef<ParsedRawSyntaxNode> Children;
31+
};
32+
struct DeferredTokenNode {
33+
SourceLoc TokLoc;
34+
unsigned TokLength;
35+
StringRef LeadingTrivia;
36+
StringRef TrailingTrivia;
37+
};
2738

2839
/// Represents a raw syntax node formed by the parser.
2940
///
@@ -48,24 +59,7 @@ class ParsedRawSyntaxNode {
4859
DeferredToken,
4960
};
5061

51-
struct RecordedSyntaxNode {
52-
OpaqueSyntaxNode OpaqueNode;
53-
};
54-
struct DeferredLayoutNode {
55-
MutableArrayRef<ParsedRawSyntaxNode> Children;
56-
};
57-
struct DeferredTokenNode {
58-
SourceLoc TokLoc;
59-
unsigned TokLength;
60-
StringRef LeadingTrivia;
61-
StringRef TrailingTrivia;
62-
};
63-
64-
union {
65-
RecordedSyntaxNode RecordedData;
66-
DeferredLayoutNode DeferredLayout;
67-
DeferredTokenNode DeferredToken;
68-
};
62+
OpaqueSyntaxNode Data;
6963
/// The range of this node, including trivia.
7064
CharSourceRange Range;
7165
uint16_t SynKind;
@@ -74,38 +68,43 @@ class ParsedRawSyntaxNode {
7468
/// Primary used for capturing a deferred missing token.
7569
bool IsMissing = false;
7670

77-
ParsedRawSyntaxNode(syntax::SyntaxKind k, CharSourceRange r,
78-
MutableArrayRef<ParsedRawSyntaxNode> deferredNodes)
79-
: DeferredLayout({deferredNodes}), Range(r), SynKind(uint16_t(k)),
80-
TokKind(uint16_t(tok::unknown)), DK(DataKind::DeferredLayout) {
81-
assert(getKind() == k && "Syntax kind with too large value!");
82-
}
83-
84-
ParsedRawSyntaxNode(tok tokKind, SourceLoc tokLoc, unsigned tokLength,
85-
StringRef leadingTrivia, StringRef trailingTrivia)
86-
: DeferredToken{tokLoc, tokLength, leadingTrivia, trailingTrivia},
87-
Range{tokLoc.getAdvancedLoc(-leadingTrivia.size()),
88-
(unsigned)leadingTrivia.size() + tokLength +
89-
(unsigned)trailingTrivia.size()},
90-
SynKind(uint16_t(syntax::SyntaxKind::Token)),
91-
TokKind(uint16_t(tokKind)), DK(DataKind::DeferredToken) {
92-
assert(getTokenKind() == tokKind && "Token kind is too large value!");
93-
}
9471
ParsedRawSyntaxNode(const ParsedRawSyntaxNode &other) = delete;
9572
ParsedRawSyntaxNode &operator=(const ParsedRawSyntaxNode &other) = delete;
9673

9774
public:
9875
ParsedRawSyntaxNode()
99-
: RecordedData{}, Range(), SynKind(uint16_t(syntax::SyntaxKind::Unknown)),
76+
: Data(nullptr), Range(), SynKind(uint16_t(syntax::SyntaxKind::Unknown)),
10077
TokKind(uint16_t(tok::unknown)), DK(DataKind::Null) {}
10178

102-
ParsedRawSyntaxNode(syntax::SyntaxKind k, tok tokKind, CharSourceRange r,
103-
OpaqueSyntaxNode n, bool IsMissing = false)
104-
: RecordedData{n}, Range(r), SynKind(uint16_t(k)),
105-
TokKind(uint16_t(tokKind)), DK(DataKind::Recorded),
106-
IsMissing(IsMissing) {
107-
assert(getKind() == k && "Syntax kind with too large value!");
108-
assert(getTokenKind() == tokKind && "Token kind with too large value!");
79+
ParsedRawSyntaxNode(OpaqueSyntaxNode Opaque, CharSourceRange Range,
80+
syntax::SyntaxKind SynKind, tok TokKind, DataKind DK,
81+
bool IsMissing)
82+
: Data(Opaque), Range(Range), SynKind(uint16_t(SynKind)),
83+
TokKind(uint16_t(TokKind)), DK(DK), IsMissing(IsMissing) {
84+
assert(getKind() == SynKind && "Syntax kind with too large value!");
85+
assert(getTokenKind() == TokKind && "Token kind with too large value!");
86+
assert(DK == DataKind::Recorded);
87+
}
88+
89+
ParsedRawSyntaxNode(const DeferredLayoutNode *Layout, CharSourceRange Range,
90+
syntax::SyntaxKind SynKind, tok TokKind, DataKind DK,
91+
bool IsMissing)
92+
: Data(Layout), Range(Range), SynKind(uint16_t(SynKind)),
93+
TokKind(uint16_t(TokKind)), DK(DK), IsMissing(IsMissing) {
94+
assert(getKind() == SynKind && "Syntax kind with too large value!");
95+
assert(getTokenKind() == TokKind && "Token kind with too large value!");
96+
assert(DK == DataKind::DeferredLayout);
97+
}
98+
99+
ParsedRawSyntaxNode(const DeferredTokenNode *Token, CharSourceRange Range,
100+
syntax::SyntaxKind SynKind, tok TokKind, DataKind DK,
101+
bool IsMissing)
102+
: Data(Token), Range(Range), SynKind(uint16_t(SynKind)),
103+
TokKind(uint16_t(TokKind)), DK(DK), IsMissing(IsMissing) {
104+
assert(getKind() == SynKind && "Syntax kind with too large value!");
105+
assert(getTokenKind() == TokKind && "Token kind with too large value!");
106+
assert(getKind() == syntax::SyntaxKind::Token);
107+
assert(DK == DataKind::DeferredToken);
109108
}
110109

111110
#ifndef NDEBUG
@@ -122,19 +121,7 @@ class ParsedRawSyntaxNode {
122121
ParsedRawSyntaxNode &operator=(ParsedRawSyntaxNode &&other) {
123122
assert(ensureDataIsNotRecorded() &&
124123
"recorded data is being destroyed by assignment");
125-
switch (other.DK) {
126-
case DataKind::Null:
127-
break;
128-
case DataKind::Recorded:
129-
RecordedData = std::move(other.RecordedData);
130-
break;
131-
case DataKind::DeferredLayout:
132-
DeferredLayout = std::move(other.DeferredLayout);
133-
break;
134-
case DataKind::DeferredToken:
135-
DeferredToken = std::move(other.DeferredToken);
136-
break;
137-
}
124+
Data = std::move(other.Data);
138125
Range = std::move(other.Range);
139126
SynKind = std::move(other.SynKind);
140127
TokKind = std::move(other.TokKind);
@@ -172,7 +159,7 @@ class ParsedRawSyntaxNode {
172159
bool isMissing() const { return IsMissing; }
173160

174161
void reset() {
175-
RecordedData = {};
162+
Data = nullptr;
176163
SynKind = uint16_t(syntax::SyntaxKind::Unknown);
177164
TokKind = uint16_t(tok::unknown);
178165
DK = DataKind::Null;
@@ -181,19 +168,7 @@ class ParsedRawSyntaxNode {
181168

182169
ParsedRawSyntaxNode unsafeCopy() const {
183170
ParsedRawSyntaxNode copy;
184-
switch (DK) {
185-
case DataKind::DeferredLayout:
186-
copy.DeferredLayout = DeferredLayout;
187-
break;
188-
case DataKind::DeferredToken:
189-
copy.DeferredToken = DeferredToken;
190-
break;
191-
case DataKind::Recorded:
192-
copy.RecordedData = RecordedData;
193-
break;
194-
case DataKind::Null:
195-
break;
196-
}
171+
copy.Data = Data;
197172
copy.Range = Range;
198173
copy.SynKind = SynKind;
199174
copy.TokKind = TokKind;
@@ -209,11 +184,11 @@ class ParsedRawSyntaxNode {
209184

210185
const OpaqueSyntaxNode &getOpaqueNode() const {
211186
assert(isRecorded());
212-
return RecordedData.OpaqueNode;
187+
return Data;
213188
}
214189
OpaqueSyntaxNode takeOpaqueNode() {
215190
assert(isRecorded());
216-
auto opaque = RecordedData.OpaqueNode;
191+
auto opaque = Data;
217192
reset();
218193
return opaque;
219194
}
@@ -222,26 +197,19 @@ class ParsedRawSyntaxNode {
222197

223198
ArrayRef<ParsedRawSyntaxNode> getDeferredChildren() const {
224199
assert(DK == DataKind::DeferredLayout);
225-
return DeferredLayout.Children;
200+
return static_cast<const DeferredLayoutNode *>(Data)->Children;
226201
}
227202

228203
MutableArrayRef<ParsedRawSyntaxNode> getDeferredChildren() {
229204
assert(DK == DataKind::DeferredLayout);
230-
return DeferredLayout.Children;
205+
return static_cast<const DeferredLayoutNode *>(Data)->Children;
231206
}
232207

233208
ParsedRawSyntaxNode copyDeferred() const {
209+
assert(DK == DataKind::DeferredLayout ||
210+
DK == DataKind::DeferredToken && "node not deferred");
234211
ParsedRawSyntaxNode copy;
235-
switch (DK) {
236-
case DataKind::DeferredLayout:
237-
copy.DeferredLayout = DeferredLayout;
238-
break;
239-
case DataKind::DeferredToken:
240-
copy.DeferredToken = DeferredToken;
241-
break;
242-
default:
243-
llvm_unreachable("node not deferred");
244-
}
212+
copy.Data = Data;
245213
copy.Range = Range;
246214
copy.SynKind = SynKind;
247215
copy.TokKind = TokKind;
@@ -254,15 +222,18 @@ class ParsedRawSyntaxNode {
254222

255223
CharSourceRange getDeferredTokenRange() const {
256224
assert(DK == DataKind::DeferredToken);
257-
return CharSourceRange{DeferredToken.TokLoc, DeferredToken.TokLength};
225+
auto DeferredToken = static_cast<const DeferredTokenNode *>(Data);
226+
return CharSourceRange{DeferredToken->TokLoc, DeferredToken->TokLength};
258227
}
259228
StringRef getDeferredLeadingTrivia() const {
260229
assert(DK == DataKind::DeferredToken);
261-
return DeferredToken.LeadingTrivia;
230+
auto DeferredToken = static_cast<const DeferredTokenNode *>(Data);
231+
return DeferredToken->LeadingTrivia;
262232
}
263233
StringRef getDeferredTrailingTrivia() const {
264234
assert(DK == DataKind::DeferredToken);
265-
return DeferredToken.TrailingTrivia;
235+
auto DeferredToken = static_cast<const DeferredTokenNode *>(Data);
236+
return DeferredToken->TrailingTrivia;
266237
}
267238

268239
//==========================================================================//

lib/Parse/ParsedRawSyntaxRecorder.cpp

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,18 @@ ParsedRawSyntaxRecorder::recordToken(tok tokKind, CharSourceRange tokRange,
4444
CharSourceRange range(offset, length);
4545
OpaqueSyntaxNode n =
4646
SPActions->recordToken(tokKind, leadingTrivia, trailingTrivia, range);
47-
return ParsedRawSyntaxNode(SyntaxKind::Token, tokKind, range, n);
47+
return ParsedRawSyntaxNode(n, range, SyntaxKind::Token, tokKind,
48+
ParsedRawSyntaxNode::DataKind::Recorded,
49+
/*IsMissing=*/false);
4850
}
4951

5052
ParsedRawSyntaxNode
5153
ParsedRawSyntaxRecorder::recordMissingToken(tok tokenKind, SourceLoc loc) {
5254
CharSourceRange range{loc, 0};
5355
OpaqueSyntaxNode n = SPActions->recordMissingToken(tokenKind, loc);
54-
return ParsedRawSyntaxNode{SyntaxKind::Token, tokenKind, range, n,
55-
/*isMissing=*/true};
56+
return ParsedRawSyntaxNode(n, range, SyntaxKind::Token, tokenKind,
57+
ParsedRawSyntaxNode::DataKind::Recorded,
58+
/*isMissing=*/true);
5659
}
5760

5861
static ParsedRawSyntaxNode
@@ -102,15 +105,19 @@ ParsedRawSyntaxRecorder::recordRawSyntax(SyntaxKind kind,
102105
range = CharSourceRange{offset, length};
103106
}
104107
OpaqueSyntaxNode n = SPActions->recordRawSyntax(kind, subnodes, range);
105-
return ParsedRawSyntaxNode{kind, tok::unknown, range, n};
108+
return ParsedRawSyntaxNode(n, range, kind, tok::unknown,
109+
ParsedRawSyntaxNode::DataKind::Recorded,
110+
/*IsMissing=*/false);
106111
}
107112

108113
ParsedRawSyntaxNode
109114
ParsedRawSyntaxRecorder::recordEmptyRawSyntaxCollection(SyntaxKind kind,
110115
SourceLoc loc) {
111116
CharSourceRange range{loc, 0};
112117
OpaqueSyntaxNode n = SPActions->recordRawSyntax(kind, {}, range);
113-
return ParsedRawSyntaxNode{kind, tok::unknown, range, n};
118+
return ParsedRawSyntaxNode(n, range, kind, tok::unknown,
119+
ParsedRawSyntaxNode::DataKind::Recorded,
120+
/*IsMissing=*/false);
114121
}
115122

116123
/// Create a deferred layout node.
@@ -119,7 +126,10 @@ ParsedRawSyntaxNode ParsedRawSyntaxRecorder::makeDeferred(
119126
SyntaxParsingContext &ctx) {
120127
CharSourceRange range;
121128
if (deferredNodes.empty()) {
122-
return ParsedRawSyntaxNode(k, range, {});
129+
auto Data = new DeferredLayoutNode{{}};
130+
return ParsedRawSyntaxNode(Data, range, k, tok::NUM_TOKENS,
131+
ParsedRawSyntaxNode::DataKind::DeferredLayout,
132+
/*IsMissing=*/false);
123133
}
124134
ParsedRawSyntaxNode *newPtr =
125135
ctx.getScratchAlloc().Allocate<ParsedRawSyntaxNode>(deferredNodes.size());
@@ -143,27 +153,38 @@ ParsedRawSyntaxNode ParsedRawSyntaxRecorder::makeDeferred(
143153
// uninitialized move;
144154
::new (static_cast<void *>(ptr++)) ParsedRawSyntaxNode(std::move(node));
145155
}
146-
return ParsedRawSyntaxNode(
147-
k, range, llvm::makeMutableArrayRef(newPtr, deferredNodes.size()));
156+
auto Data = new DeferredLayoutNode{
157+
llvm::makeMutableArrayRef(newPtr, deferredNodes.size())};
158+
return ParsedRawSyntaxNode(Data, range, k, tok::NUM_TOKENS,
159+
ParsedRawSyntaxNode::DataKind::DeferredLayout,
160+
/*IsMissing=*/false);
148161
}
149162

150163
/// Create a deferred token node.
151164
ParsedRawSyntaxNode
152165
ParsedRawSyntaxRecorder::makeDeferred(Token tok, StringRef leadingTrivia,
153166
StringRef trailingTrivia) {
154167
CharSourceRange tokRange = tok.getRange();
155-
return ParsedRawSyntaxNode(tok.getKind(), tokRange.getStart(),
156-
tokRange.getByteLength(), leadingTrivia,
157-
trailingTrivia);
168+
auto Data =
169+
new DeferredTokenNode{tokRange.getStart(), tokRange.getByteLength(),
170+
leadingTrivia, trailingTrivia};
171+
CharSourceRange RangeWithTrivia = CharSourceRange(
172+
tokRange.getStart().getAdvancedLoc(-leadingTrivia.size()),
173+
(unsigned)leadingTrivia.size() + tokRange.getByteLength() +
174+
(unsigned)trailingTrivia.size());
175+
return ParsedRawSyntaxNode(
176+
Data, RangeWithTrivia, SyntaxKind::Token, tok.getKind(),
177+
ParsedRawSyntaxNode::DataKind::DeferredToken, /*IsMissing=*/false);
158178
}
159179

160180
ParsedRawSyntaxNode
161181
ParsedRawSyntaxRecorder::makeDeferredMissing(tok tokKind, SourceLoc loc) {
162-
auto raw = ParsedRawSyntaxNode(tokKind, loc, /*tokLength=*/0,
163-
/*leadingTrivia=*/StringRef(),
164-
/*trailingTrivia=*/StringRef());
165-
raw.IsMissing = true;
166-
return raw;
182+
auto Data =
183+
new DeferredTokenNode{loc, /*TokLength=*/0, /*leadingTrivia=*/StringRef(),
184+
/*trailingTrivia=*/StringRef()};
185+
return ParsedRawSyntaxNode(
186+
Data, CharSourceRange(loc, /*Length=*/0), SyntaxKind::Token, tokKind,
187+
ParsedRawSyntaxNode::DataKind::DeferredToken, /*IsMissing=*/true);
167188
}
168189

169190
ParsedRawSyntaxNode
@@ -176,7 +197,12 @@ ParsedRawSyntaxRecorder::lookupNode(size_t lexerOffset, SourceLoc loc,
176197
return ParsedRawSyntaxNode::null();
177198
}
178199
CharSourceRange range{loc, unsigned(length)};
179-
return ParsedRawSyntaxNode{kind, tok::unknown, range, n};
200+
return ParsedRawSyntaxNode{n,
201+
range,
202+
kind,
203+
tok::unknown,
204+
ParsedRawSyntaxNode::DataKind::Recorded,
205+
/*IsMissing=*/false};
180206
}
181207

182208
#ifndef NDEBUG

0 commit comments

Comments
 (0)