Skip to content

Commit 4806fb1

Browse files
committed
[ParsedRawSyntaxNode] Explicitely specify if a ParsedRawSyntaxNode is null using a DataKind
Avoid implicitely assuming 'null' node if its OpaqueSyntaxNode is null, there should be no interpretation of OpaqueSyntaxNode values, a SyntaxParseActions implementation should be able to return null pointers as OpaqueSyntaxNode.
1 parent 668fa1d commit 4806fb1

File tree

3 files changed

+24
-6
lines changed

3 files changed

+24
-6
lines changed

include/swift/Parse/ParsedRawSyntaxNode.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ typedef void *OpaqueSyntaxNode;
3939
/// in the current parsing context.
4040
class ParsedRawSyntaxNode {
4141
enum class DataKind: uint8_t {
42+
Null,
4243
Recorded,
4344
DeferredLayout,
4445
DeferredToken,
@@ -90,8 +91,11 @@ class ParsedRawSyntaxNode {
9091

9192
public:
9293
ParsedRawSyntaxNode()
93-
: ParsedRawSyntaxNode(syntax::SyntaxKind::Unknown, tok::unknown,
94-
{}, nullptr) {}
94+
: RecordedData{},
95+
SynKind(uint16_t(syntax::SyntaxKind::Unknown)),
96+
TokKind(uint16_t(tok::unknown)),
97+
DK(DataKind::Null) {
98+
}
9599

96100
ParsedRawSyntaxNode(syntax::SyntaxKind k, tok tokKind,
97101
CharSourceRange r, OpaqueSyntaxNode n)
@@ -104,6 +108,8 @@ class ParsedRawSyntaxNode {
104108

105109
ParsedRawSyntaxNode(const ParsedRawSyntaxNode &other) {
106110
switch (other.DK) {
111+
case DataKind::Null:
112+
break;
107113
case DataKind::Recorded:
108114
new(&this->RecordedData)RecordedSyntaxNode(other.RecordedData);
109115
break;
@@ -121,6 +127,8 @@ class ParsedRawSyntaxNode {
121127

122128
ParsedRawSyntaxNode(ParsedRawSyntaxNode &&other) {
123129
switch (other.DK) {
130+
case DataKind::Null:
131+
break;
124132
case DataKind::Recorded:
125133
new(&this->RecordedData)RecordedSyntaxNode(
126134
std::move(other.RecordedData));
@@ -166,7 +174,7 @@ class ParsedRawSyntaxNode {
166174
}
167175

168176
bool isNull() const {
169-
return isRecorded() && RecordedData.OpaqueNode == nullptr;
177+
return DK == DataKind::Null;
170178
}
171179

172180
bool isRecorded() const { return DK == DataKind::Recorded; }
@@ -247,6 +255,8 @@ class ParsedRawSyntaxNode {
247255
private:
248256
void releaseMemory() {
249257
switch (DK) {
258+
case DataKind::Null:
259+
break;
250260
case DataKind::Recorded:
251261
RecordedData.~RecordedSyntaxNode(); break;
252262
case DataKind::DeferredLayout:

lib/Parse/ParsedRawSyntaxRecorder.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ ParsedRawSyntaxRecorder::recordMissingToken(tok tokenKind, SourceLoc loc) {
5656

5757
static ParsedRawSyntaxNode
5858
getRecordedNode(const ParsedRawSyntaxNode &node, ParsedRawSyntaxRecorder &rec) {
59-
if (node.isRecorded())
59+
if (node.isNull() || node.isRecorded())
6060
return node;
6161
if (node.isDeferredLayout())
6262
return rec.recordRawSyntax(node.getKind(), node.getDeferredChildren());
@@ -78,8 +78,10 @@ ParsedRawSyntaxRecorder::recordRawSyntax(SyntaxKind kind,
7878
unsigned length = 0;
7979
for (const auto &elem : elements) {
8080
auto subnode = getRecordedNode(elem, *this);
81-
subnodes.push_back(subnode.getOpaqueNode());
82-
if (!subnode.isNull()) {
81+
if (subnode.isNull()) {
82+
subnodes.push_back(nullptr);
83+
} else {
84+
subnodes.push_back(subnode.getOpaqueNode());
8385
auto range = subnode.getRange();
8486
if (range.isValid()) {
8587
if (offset.isInvalid())
@@ -108,6 +110,9 @@ ParsedRawSyntaxRecorder::lookupNode(size_t lexerOffset, SourceLoc loc,
108110
size_t length;
109111
OpaqueSyntaxNode n;
110112
std::tie(length, n) = SPActions->lookupNode(lexerOffset, kind);
113+
if (length == 0) {
114+
return ParsedRawSyntaxNode::null();
115+
}
111116
CharSourceRange range{loc, unsigned(length)};
112117
return ParsedRawSyntaxNode{kind, tok::unknown, range, n};
113118
}

lib/Parse/Parser.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,9 @@ OpaqueSyntaxNode ParserUnit::parse() {
11231123
Done = P.Tok.is(tok::eof);
11241124
}
11251125
auto rawNode = P.finalizeSyntaxTree();
1126+
if (rawNode.isNull()) {
1127+
return nullptr;
1128+
}
11261129
return rawNode.getOpaqueNode();
11271130
}
11281131

0 commit comments

Comments
 (0)