Skip to content

Commit 94f0c14

Browse files
committed
[SyntaxParse] Return dedicated pointer from HiddenLibSyntaxAction
SyntaxParseActions::recordToken() et al. may return the same pointer value for different nodes (e.g. `nullptr`). So we cannot use DenseMap to associate the node from the explicit syntax parsing actions to libSyntax node. Instead, use a structure that wraps them.
1 parent 27f2f36 commit 94f0c14

File tree

8 files changed

+100
-50
lines changed

8 files changed

+100
-50
lines changed

include/swift/Parse/HiddenLibSyntaxAction.h

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,40 @@
1515

1616
#include "swift/Parse/SyntaxParseActions.h"
1717
#include "swift/SyntaxParse/SyntaxTreeCreator.h"
18-
#include "llvm/ADT/DenseMap.h"
18+
#include "llvm/Support/Allocator.h"
1919

2020
namespace swift {
21+
namespace syntax {
22+
class RawSyntax;
23+
}
24+
2125
/// Holds an explicitly provided action and uses it to handle all function
2226
/// calls. Also hides an implicit SyntaxTreeCreator and ensures libSyntax nodes
2327
/// are always created. Provides an interface to map results of the explicitly
2428
/// provided action to the hidden libSyntax action.
2529
// todo [gsoc]: remove when possible
2630
class HiddenLibSyntaxAction : public SyntaxParseActions {
31+
32+
struct Node {
33+
OpaqueSyntaxNode ExplicitActionNode;
34+
OpaqueSyntaxNode LibSyntaxNode;
35+
36+
Node(OpaqueSyntaxNode ExplicitActionNode, OpaqueSyntaxNode LibSyntaxNode)
37+
: ExplicitActionNode(ExplicitActionNode), LibSyntaxNode(LibSyntaxNode) {
38+
}
39+
};
40+
2741
std::shared_ptr<SyntaxParseActions> ExplicitAction;
2842
std::shared_ptr<SyntaxTreeCreator> LibSyntaxAction;
29-
llvm::DenseMap<OpaqueSyntaxNode, OpaqueSyntaxNode> OpaqueNodeMap;
43+
llvm::SpecificBumpPtrAllocator<Node> NodeAllocator;
3044

3145
bool areBothLibSyntax() {
3246
return ExplicitAction->getOpaqueKind() == OpaqueSyntaxNodeKind::LibSyntax;
3347
}
3448

49+
OpaqueSyntaxNode makeHiddenNode(OpaqueSyntaxNode explicitActionNode,
50+
OpaqueSyntaxNode libSyntaxNode);
51+
3552
public:
3653
HiddenLibSyntaxAction(
3754
const std::shared_ptr<SyntaxParseActions> &SPActions,
@@ -57,14 +74,18 @@ class HiddenLibSyntaxAction : public SyntaxParseActions {
5774
return ExplicitAction->getOpaqueKind();
5875
}
5976

60-
/// Returns the libSyntax node corresponding to the provided node that has
61-
/// been created by the explicit action.
62-
OpaqueSyntaxNode getLibSyntaxNodeFor(OpaqueSyntaxNode explicitNode);
77+
/// Returns the libSyntax node from the specified node that has been created
78+
/// by this action.
79+
syntax::RawSyntax *getLibSyntaxNodeFor(OpaqueSyntaxNode node);
80+
81+
/// Returns the node created by explicit syntax action from the specified
82+
/// node that has been created by this action.
83+
OpaqueSyntaxNode getExplicitNodeFor(OpaqueSyntaxNode node);
6384

6485
bool isReleaseNeeded() {
6586
return ExplicitAction == LibSyntaxAction || !areBothLibSyntax();
6687
}
67-
88+
6889
/// Returns the underlying libSyntax SyntaxTreeCreator.
6990
std::shared_ptr<SyntaxTreeCreator> getLibSyntaxAction() {
7091
return LibSyntaxAction;

include/swift/Parse/LibSyntaxGenerator.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,13 @@ class LibSyntaxGenerator {
6666

6767
template <typename SyntaxNode>
6868
SyntaxNode getLibSyntaxNodeFor(OpaqueSyntaxNode Node) {
69-
auto Raw = static_cast<RawSyntax *>(Actions->getLibSyntaxNodeFor(Node));
70-
return make<SyntaxNode>(Raw);
69+
return make<SyntaxNode>(Actions->getLibSyntaxNodeFor(Node));
7170
}
7271

73-
void releaseLibSyntaxNodeIfNeededFor(OpaqueSyntaxNode Node) {
74-
if (!Actions->isReleaseNeeded())
75-
return;
76-
auto Raw = static_cast<RawSyntax *>(Actions->getLibSyntaxNodeFor(Node));
77-
Raw->Release();
72+
OpaqueSyntaxNode finalizeNode(OpaqueSyntaxNode Node) {
73+
if (Actions->isReleaseNeeded())
74+
Actions->getLibSyntaxNodeFor(Node)->Release();
75+
return Actions->getExplicitNodeFor(Node);
7876
}
7977
};
8078
} // namespace swift

include/swift/Parse/Parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ class Parser {
402402

403403
/// Calling this function to finalize libSyntax tree creation without destroying
404404
/// the parser instance.
405-
ParsedRawSyntaxNode finalizeSyntaxTree() {
405+
OpaqueSyntaxNode finalizeSyntaxTree() {
406406
assert(Tok.is(tok::eof) && "not done parsing yet");
407407
return SyntaxContext->finalizeRoot();
408408
}

include/swift/Parse/SyntaxParsingContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ class alignas(1 << SyntaxAlignInBits) SyntaxParsingContext {
350350
/// This function will be called during the destroying of a root syntax
351351
/// parsing context. However, we can explicitly call this function to get
352352
/// the syntax tree before closing the root context.
353-
ParsedRawSyntaxNode finalizeRoot();
353+
OpaqueSyntaxNode finalizeRoot();
354354

355355
/// Make a missing node corresponding to the given token kind and
356356
/// push this node into the context. The synthesized node can help

lib/Parse/HiddenLibSyntaxAction.cpp

Lines changed: 59 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,65 +28,100 @@ using namespace swift;
2828
using namespace swift::syntax;
2929
using namespace llvm;
3030

31+
OpaqueSyntaxNode
32+
HiddenLibSyntaxAction::makeHiddenNode(OpaqueSyntaxNode explicitActionNode,
33+
OpaqueSyntaxNode libSyntaxNode) {
34+
auto dat = NodeAllocator.Allocate();
35+
return new (dat) Node(explicitActionNode, libSyntaxNode);
36+
}
37+
3138
OpaqueSyntaxNode HiddenLibSyntaxAction::recordToken(
3239
tok tokenKind, ArrayRef<ParsedTriviaPiece> leadingTrivia,
3340
ArrayRef<ParsedTriviaPiece> trailingTrivia, CharSourceRange range) {
3441
OpaqueSyntaxNode primaryNode = ExplicitAction->recordToken(
3542
tokenKind, leadingTrivia, trailingTrivia, range);
43+
OpaqueSyntaxNode secondaryNode = nullptr;
3644

37-
if (!areBothLibSyntax()) {
38-
OpaqueSyntaxNode secondaryNode = LibSyntaxAction->recordToken(
39-
tokenKind, leadingTrivia, trailingTrivia, range);
40-
OpaqueNodeMap[primaryNode] = secondaryNode;
45+
if (areBothLibSyntax()) {
46+
secondaryNode = primaryNode;
47+
} else {
48+
secondaryNode = LibSyntaxAction->recordToken(tokenKind, leadingTrivia,
49+
trailingTrivia, range);
4150
}
4251

43-
return primaryNode;
52+
return makeHiddenNode(primaryNode, secondaryNode);
4453
}
4554

4655
OpaqueSyntaxNode HiddenLibSyntaxAction::recordMissingToken(tok tokenKind,
4756
SourceLoc loc) {
4857
OpaqueSyntaxNode primaryNode =
4958
ExplicitAction->recordMissingToken(tokenKind, loc);
59+
OpaqueSyntaxNode secondaryNode = nullptr;
5060

51-
if (!areBothLibSyntax()) {
52-
OpaqueSyntaxNode secondaryNode =
53-
LibSyntaxAction->recordMissingToken(tokenKind, loc);
54-
OpaqueNodeMap[primaryNode] = secondaryNode;
61+
if (areBothLibSyntax()) {
62+
secondaryNode = primaryNode;
63+
} else {
64+
secondaryNode = LibSyntaxAction->recordMissingToken(tokenKind, loc);
5565
}
5666

57-
return primaryNode;
67+
return makeHiddenNode(primaryNode, secondaryNode);
5868
}
5969

6070
OpaqueSyntaxNode
6171
HiddenLibSyntaxAction::recordRawSyntax(syntax::SyntaxKind kind,
6272
ArrayRef<OpaqueSyntaxNode> elements,
6373
CharSourceRange range) {
64-
OpaqueSyntaxNode primaryNode =
65-
ExplicitAction->recordRawSyntax(kind, elements, range);
74+
OpaqueSyntaxNode primaryNode = nullptr;
75+
OpaqueSyntaxNode secondaryNode = nullptr;
76+
77+
{
78+
SmallVector<OpaqueSyntaxNode, 4> primaryElements;
79+
primaryElements.reserve(elements.size());
80+
for (auto element : elements) {
81+
OpaqueSyntaxNode primaryElement = nullptr;
82+
if (element)
83+
primaryElement = ((Node *)element)->ExplicitActionNode;
84+
primaryElements.push_back(primaryElement);
85+
}
6686

67-
if (!areBothLibSyntax()) {
87+
primaryNode = ExplicitAction->recordRawSyntax(kind, primaryElements, range);
88+
}
89+
90+
if (areBothLibSyntax()) {
91+
secondaryNode = primaryNode;
92+
} else {
6893
SmallVector<OpaqueSyntaxNode, 4> secondaryElements;
6994
secondaryElements.reserve(elements.size());
70-
for (auto &&element : elements) {
71-
secondaryElements.push_back(OpaqueNodeMap[element]);
95+
for (auto element : elements) {
96+
OpaqueSyntaxNode secondaryElement = nullptr;
97+
if (element)
98+
secondaryElement = ((Node *)element)->LibSyntaxNode;
99+
secondaryElements.push_back(secondaryElement);
72100
}
73-
OpaqueSyntaxNode secondaryNode =
101+
secondaryNode =
74102
LibSyntaxAction->recordRawSyntax(kind, secondaryElements, range);
75-
OpaqueNodeMap[primaryNode] = secondaryNode;
76103
}
77104

78-
return primaryNode;
105+
return makeHiddenNode(primaryNode, secondaryNode);
79106
}
80107

81108
std::pair<size_t, OpaqueSyntaxNode>
82109
HiddenLibSyntaxAction::lookupNode(size_t lexerOffset, syntax::SyntaxKind kind) {
83-
return ExplicitAction->lookupNode(lexerOffset, kind);
110+
size_t length;
111+
OpaqueSyntaxNode n;
112+
std::tie(length, n) = ExplicitAction->lookupNode(lexerOffset, kind);
113+
if (length == 0)
114+
return {0, nullptr};
115+
return {length, makeHiddenNode(n, nullptr)};
84116
}
85117

86-
OpaqueSyntaxNode
87-
HiddenLibSyntaxAction::getLibSyntaxNodeFor(OpaqueSyntaxNode explicitNode) {
88-
if (!areBothLibSyntax())
89-
return OpaqueNodeMap[explicitNode];
118+
RawSyntax *HiddenLibSyntaxAction::getLibSyntaxNodeFor(OpaqueSyntaxNode node) {
119+
auto hiddenNode = (Node *)node;
120+
return (RawSyntax *)hiddenNode->LibSyntaxNode;
121+
}
90122

91-
return explicitNode;
123+
OpaqueSyntaxNode
124+
HiddenLibSyntaxAction::getExplicitNodeFor(OpaqueSyntaxNode node) {
125+
auto hiddenNode = (Node *)node;
126+
return hiddenNode->ExplicitActionNode;
92127
}

lib/Parse/Parser.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,11 +1212,7 @@ OpaqueSyntaxNode ParserUnit::parse() {
12121212
P.parseTopLevel();
12131213
Done = P.Tok.is(tok::eof);
12141214
}
1215-
auto rawNode = P.finalizeSyntaxTree();
1216-
if (rawNode.isNull()) {
1217-
return nullptr;
1218-
}
1219-
return rawNode.getOpaqueNode();
1215+
return P.finalizeSyntaxTree();
12201216
}
12211217

12221218
Parser &ParserUnit::getParser() {

lib/Parse/SyntaxParsingContext.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,21 +272,21 @@ ParsedRawSyntaxNode SyntaxParsingContext::finalizeSourceFile() {
272272
{ itemList, EOFToken });
273273
}
274274

275-
ParsedRawSyntaxNode SyntaxParsingContext::finalizeRoot() {
275+
OpaqueSyntaxNode SyntaxParsingContext::finalizeRoot() {
276276
assert(isTopOfContextStack() && "some sub-contexts are not destructed");
277277
assert(isRoot() && "only root context can finalize the tree");
278278
assert(Mode == AccumulationMode::Root);
279279
if (getStorage().empty()) {
280-
return ParsedRawSyntaxNode::null(); // already finalized.
280+
return nullptr; // already finalized.
281281
}
282282
ParsedRawSyntaxNode root = finalizeSourceFile();
283-
getSyntaxCreator().releaseLibSyntaxNodeIfNeededFor(root.getOpaqueNode());
283+
auto opaqueRoot = getSyntaxCreator().finalizeNode(root.getOpaqueNode());
284284

285285
// Clear the parts because we will call this function again when destroying
286286
// the root context.
287287
getStorage().clear();
288288

289-
return root;
289+
return opaqueRoot;
290290
}
291291

292292
void SyntaxParsingContext::synthesize(tok Kind, SourceLoc Loc) {
@@ -356,7 +356,7 @@ SyntaxParsingContext::~SyntaxParsingContext() {
356356
auto &nodes = getStorage();
357357
for (auto i = nodes.begin()+Offset, e = nodes.end(); i != e; ++i)
358358
if (i->isRecorded())
359-
getSyntaxCreator().releaseLibSyntaxNodeIfNeededFor(i->getOpaqueNode());
359+
getSyntaxCreator().finalizeNode(i->getOpaqueNode());
360360

361361
nodes.erase(nodes.begin()+Offset, nodes.end());
362362
break;

lib/ParseSIL/ParseSIL.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ static bool parseIntoSourceFileImpl(SourceFile &SF,
165165

166166
if (STreeCreator) {
167167
auto rawNode = P.finalizeSyntaxTree();
168-
STreeCreator->acceptSyntaxRoot(rawNode.getOpaqueNode(), SF);
168+
STreeCreator->acceptSyntaxRoot(rawNode, SF);
169169
}
170170

171171
return FoundSideEffects;

0 commit comments

Comments
 (0)