Skip to content

Commit 75db3c1

Browse files
authored
Re-apply libSyntax patches after fixing ASAN issue (#12730)
* Re-apply "libSyntax: Ensure round-trip printing when we build syntax tree from parser incrementally. (#12709)" * Re-apply "libSyntax: Root parsing context should hold a reference to the current token in the parser, NFC." * Re-apply "libSyntax: avoid copying token text when lexing token syntax nodes, NFC. (#12723)" * Actually fix the container-overflow issue.
1 parent 759a9ee commit 75db3c1

File tree

11 files changed

+275
-128
lines changed

11 files changed

+275
-128
lines changed

include/swift/AST/Module.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ namespace syntax {
8383
class SourceFileSyntax;
8484
class SyntaxParsingContext;
8585
class SyntaxParsingContextRoot;
86-
struct RawTokenInfo;
86+
struct RawSyntaxInfo;
8787
}
8888

8989
/// Discriminator for file-units.
@@ -1092,7 +1092,7 @@ class SourceFile final : public FileUnit {
10921092
Optional<std::vector<Token>> AllCorrectedTokens;
10931093

10941094
/// All of the raw token syntax nodes in the underlying source.
1095-
std::vector<syntax::RawTokenInfo> AllRawTokenSyntax;
1095+
std::vector<syntax::RawSyntaxInfo> AllRawTokenSyntax;
10961096

10971097
SourceFileSyntaxInfo &SyntaxInfo;
10981098

include/swift/Parse/Lexer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace swift {
3030

3131
namespace syntax {
3232
struct RawTokenSyntax;
33-
struct RawTokenInfo;
33+
struct RawSyntaxInfo;
3434
}
3535

3636
/// Given a pointer to the starting byte of a UTF8 character, validate it and
@@ -246,7 +246,7 @@ class Lexer {
246246
}
247247

248248
/// Lex a full token including leading and trailing trivia.
249-
syntax::RawTokenInfo fullLex();
249+
syntax::RawSyntaxInfo fullLex();
250250

251251
bool isKeepingComments() const {
252252
return RetainComments == CommentRetentionMode::ReturnAsTokens;

include/swift/Parse/Parser.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ namespace swift {
5656
namespace syntax {
5757
class AbsolutePosition;
5858
class SyntaxParsingContext;
59-
struct RawTokenInfo;
59+
struct RawSyntaxInfo;
6060
struct RawTokenSyntax;
6161
}// end of syntax namespace
6262

@@ -1434,7 +1434,7 @@ tokenizeWithTrivia(const LangOptions &LangOpts,
14341434
void populateTokenSyntaxMap(const LangOptions &LangOpts,
14351435
const SourceManager &SM,
14361436
unsigned BufferID,
1437-
std::vector<syntax::RawTokenInfo> &Result);
1437+
std::vector<syntax::RawSyntaxInfo> &Result);
14381438
} // end namespace swift
14391439

14401440
#endif

include/swift/Syntax/SyntaxParsingContext.h

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,39 @@
1313
#ifndef SWIFT_SYNTAX_PARSING_CONTEXT_H
1414
#define SWIFT_SYNTAX_PARSING_CONTEXT_H
1515

16+
#include "swift/Syntax/Syntax.h"
17+
1618
namespace swift {
1719
class SourceLoc;
1820
class SourceFile;
21+
class Token;
1922

2023
namespace syntax {
2124
struct RawTokenSyntax;
25+
struct RawSyntax;
2226
enum class SyntaxKind;
2327

24-
struct RawTokenInfo {
25-
SourceLoc Loc;
26-
RC<RawTokenSyntax> Token;
28+
/// The handler for parser to generate libSyntax entities.
29+
struct RawSyntaxInfo {
30+
/// Start location of this syntax node.
31+
SourceLoc StartLoc;
32+
33+
/// The number of tokens belong to the syntax node.
34+
unsigned TokCount;
35+
36+
/// The raw node.
37+
RC<RawSyntax> RawNode;
38+
RawSyntaxInfo(SourceLoc StartLoc, RC<RawSyntax> RawNode):
39+
RawSyntaxInfo(StartLoc, 1, RawNode) {}
40+
RawSyntaxInfo(SourceLoc StartLoc, unsigned TokCount, RC<RawSyntax> RawNode);
41+
42+
template <typename SyntaxNode>
43+
SyntaxNode makeSyntax() const { return make<SyntaxNode>(RawNode); }
44+
45+
template <typename RawSyntaxNode>
46+
RC<RawSyntaxNode> getRaw() const {
47+
return RC<RawSyntaxNode>(cast<RawSyntaxNode>(RawNode));
48+
}
2749
};
2850

2951
enum class SyntaxParsingContextKind: uint8_t {
@@ -35,11 +57,12 @@ enum class SyntaxParsingContextKind: uint8_t {
3557
/// create syntax nodes.
3658
class SyntaxParsingContext {
3759
protected:
38-
SyntaxParsingContext(bool Enabled);
60+
SyntaxParsingContext(SourceFile &SF, unsigned BufferID, Token &Tok);
3961
SyntaxParsingContext(SyntaxParsingContext &Another);
4062
public:
4163
struct ContextInfo;
4264
ContextInfo &ContextData;
65+
const Token &Tok;
4366

4467
// Add a token syntax at the given source location to the context; this
4568
// token node can be used to build more complex syntax nodes in later call
@@ -61,12 +84,10 @@ class SyntaxParsingContext {
6184
// of all other entity-specific contexts. This is the context Parser
6285
// has when the parser instance is firstly created.
6386
class SyntaxParsingContextRoot: public SyntaxParsingContext {
87+
SourceFile &File;
6488
public:
65-
struct GlobalInfo;
66-
67-
// Contains global information of the source file under parsing.
68-
GlobalInfo &GlobalData;
69-
SyntaxParsingContextRoot(SourceFile &SF, unsigned BufferID);
89+
SyntaxParsingContextRoot(SourceFile &File, unsigned BufferID, Token &Tok):
90+
SyntaxParsingContext(File, BufferID, Tok), File(File) {}
7091
~SyntaxParsingContextRoot();
7192
void addTokenSyntax(SourceLoc Loc) override {};
7293
void makeNode(SyntaxKind Kind) override {};
@@ -75,21 +96,22 @@ class SyntaxParsingContextRoot: public SyntaxParsingContext {
7596
};
7697
};
7798

99+
enum class SyntaxContextKind: uint8_t{
100+
Expr,
101+
Decl,
102+
};
103+
78104
// The base class for contexts that are created from a parent context.
79105
// The stack instance will set the context holder when the context
80106
// is firstly created and reset the context holder to the parent when
81107
// it's destructed.
82108
class SyntaxParsingContextChild: public SyntaxParsingContext {
83109
SyntaxParsingContext *Parent;
84110
SyntaxParsingContext *&ContextHolder;
85-
const SyntaxKind FinalKind;
111+
const SyntaxContextKind Kind;
86112
public:
87113
SyntaxParsingContextChild(SyntaxParsingContext *&ContextHolder,
88-
SyntaxKind FinalKind):
89-
SyntaxParsingContext(*ContextHolder), Parent(ContextHolder),
90-
ContextHolder(ContextHolder), FinalKind(FinalKind) {
91-
ContextHolder = this;
92-
}
114+
SyntaxContextKind Kind);
93115
~SyntaxParsingContextChild();
94116
void makeNode(SyntaxKind Kind) override;
95117
void addTokenSyntax(SourceLoc Loc) override;

lib/Parse/Lexer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -738,15 +738,15 @@ static bool rangeContainsPlaceholderEnd(const char *CurPtr,
738738
return false;
739739
}
740740

741-
syntax::RawTokenInfo Lexer::fullLex() {
741+
syntax::RawSyntaxInfo Lexer::fullLex() {
742742
if (NextToken.isEscapedIdentifier()) {
743743
LeadingTrivia.push_back(syntax::TriviaPiece::backtick());
744744
TrailingTrivia.insert(TrailingTrivia.begin(),
745745
syntax::TriviaPiece::backtick());
746746
}
747747
auto Loc = NextToken.getLoc();
748748
auto Result = syntax::RawTokenSyntax::make(NextToken.getKind(),
749-
OwnedString(NextToken.getText()).copy(),
749+
OwnedString(NextToken.getText()),
750750
syntax::SourcePresence::Present,
751751
{LeadingTrivia}, {TrailingTrivia});
752752
LeadingTrivia.clear();

lib/Parse/ParseDecl.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
#include "swift/Parse/CodeCompletionCallbacks.h"
1919
#include "swift/Parse/DelayedParsingCallbacks.h"
2020
#include "swift/Parse/ParseSILSupport.h"
21+
#include "swift/Syntax/SyntaxFactory.h"
22+
#include "swift/Syntax/TokenSyntax.h"
23+
#include "swift/Syntax/SyntaxParsingContext.h"
2124
#include "swift/Subsystems.h"
2225
#include "swift/AST/Attr.h"
2326
#include "swift/AST/DebuggerClient.h"
@@ -37,6 +40,7 @@
3740
#include <algorithm>
3841

3942
using namespace swift;
43+
using namespace syntax;
4044

4145
namespace {
4246
/// A RAII object for deciding whether this DeclKind needs special
@@ -2146,7 +2150,8 @@ void Parser::delayParseFromBeginningToHere(ParserPosition BeginParserPosition,
21462150
ParserResult<Decl>
21472151
Parser::parseDecl(ParseDeclOptions Flags,
21482152
llvm::function_ref<void(Decl*)> Handler) {
2149-
2153+
SyntaxParsingContextChild DeclParsingContext(SyntaxContext,
2154+
SyntaxContextKind::Decl);
21502155
if (Tok.is(tok::pound_if)) {
21512156
auto IfConfigResult = parseIfConfig(
21522157
[&](SmallVectorImpl<ASTNode> &Decls, bool IsActive) {

lib/Parse/ParseExpr.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ using namespace swift::syntax;
4040
/// \param isExprBasic Whether we're only parsing an expr-basic.
4141
ParserResult<Expr> Parser::parseExprImpl(Diag<> Message, bool isExprBasic) {
4242
// Start a context for creating expression syntax.
43-
SyntaxParsingContextChild ExprParsingContext(SyntaxContext, SyntaxKind::Expr);
43+
SyntaxParsingContextChild ExprParsingContext(SyntaxContext,
44+
SyntaxContextKind::Expr);
4445

4546
// If we are parsing a refutable pattern, check to see if this is the start
4647
// of a let/var/is pattern. If so, parse it to an UnresolvedPatternExpr and
@@ -1804,7 +1805,8 @@ ParserResult<Expr> Parser::parseExprStringLiteral() {
18041805
// Create a syntax node for string literal.
18051806
SyntaxContext->addTokenSyntax(Tok.getLoc());
18061807
SyntaxContext->makeNode(SyntaxKind::StringLiteralExpr);
1807-
SyntaxParsingContextChild LocalContext(SyntaxContext, SyntaxKind::Expr);
1808+
SyntaxParsingContextChild LocalContext(SyntaxContext,
1809+
SyntaxContextKind::Expr);
18081810

18091811
// FIXME: Avoid creating syntax nodes for string interpolation.
18101812
LocalContext.disable();

lib/Parse/Parser.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ swift::tokenizeWithTrivia(const LangOptions &LangOpts,
269269
syntax::AbsolutePosition>> Tokens;
270270
syntax::AbsolutePosition RunningPos;
271271
do {
272-
auto ThisToken = L.fullLex().Token;
272+
auto ThisToken = L.fullLex().getRaw<syntax::RawTokenSyntax>();
273273
auto ThisTokenPos = ThisToken->accumulateAbsolutePosition(RunningPos);
274274
Tokens.push_back({ThisToken, ThisTokenPos});
275275
} while (Tokens.back().first->isNot(tok::eof));
@@ -280,15 +280,15 @@ swift::tokenizeWithTrivia(const LangOptions &LangOpts,
280280
void swift::populateTokenSyntaxMap(const LangOptions &LangOpts,
281281
const SourceManager &SM,
282282
unsigned BufferID,
283-
std::vector<syntax::RawTokenInfo> &Result) {
283+
std::vector<syntax::RawSyntaxInfo> &Result) {
284284
if (!Result.empty())
285285
return;
286286
Lexer L(LangOpts, SM, BufferID, /*Diags=*/nullptr, /*InSILMode=*/false,
287287
CommentRetentionMode::AttachToNextToken,
288288
TriviaRetentionMode::WithTrivia);
289289
do {
290290
Result.emplace_back(L.fullLex());
291-
if (Result.back().Token->is(tok::eof))
291+
if (Result.back().getRaw<syntax::RawTokenSyntax>()->is(tok::eof))
292292
return;
293293
} while (true);
294294
}
@@ -435,7 +435,7 @@ Parser::Parser(std::unique_ptr<Lexer> Lex, SourceFile &SF,
435435
TokReceiver(SF.shouldKeepTokens() ?
436436
new TokenRecorder(SF) :
437437
new ConsumeTokenReceiver()),
438-
SyntaxContext(new syntax::SyntaxParsingContextRoot(SF, L->getBufferID())) {
438+
SyntaxContext(new syntax::SyntaxParsingContextRoot(SF, L->getBufferID(), Tok)) {
439439

440440
State = PersistentState;
441441
if (!State) {

0 commit comments

Comments
 (0)